Week of '+weekStart.toLocaleDateString('en',{month:'short',day:'numeric'})+' - '+weekEnd.toLocaleDateString('en',{month:'short',day:'numeric',year:'numeric'})+'
';
h+='{const k=(n+h/30)%12;const color=l-a*Math.max(Math.min(k-3,9-k,1),-1);return Math.round(255*color).toString(16).padStart(2,'0');};return'#'+f(0)+f(8)+f(4);};
window._genPalette=function(type){
const hex=document.getElementById('pal-base').value;const[h,s,l]=window._hexToHSL(hex);
let colors=[];
if(type==='analogous'){for(let i=-2;i<=2;i++)colors.push(window._hslToHex((h+i*30+360)%360,s,l));}
else if(type==='complementary'){colors=[hex,window._hslToHex((h+180)%360,s,l),window._hslToHex((h+120)%360,s,l),window._hslToHex((h+240)%360,s,l),window._hslToHex((h+60)%360,s,l)];}
else{for(let i=0;i<5;i++)colors.push(window._hslToHex(h,s,Math.max(10,l-20+i*10)));}
const el=document.getElementById('pal-output');el.innerHTML='';
colors.forEach(c=>{el.innerHTML+='';});
};
window._genPalette('analogous');
}
function showPythonPipRef(){
let p=document.getElementById('pip-ref-panel');if(p)p.remove();
const cmds={'Virtual Environments':['python -m venv venv','source venv/bin/activate','deactivate','python -m venv --clear venv','pip install virtualenv','virtualenv myenv','conda create -n myenv python=3.11','conda activate myenv','conda deactivate','conda env list'],'Package Management':['pip install package','pip install package==1.0.0','pip install -r requirements.txt','pip install -e . (editable)','pip uninstall package','pip install --upgrade package','pip list','pip list --outdated','pip show package','pip freeze > requirements.txt'],'Tools & Linting':['pip install black','black .','pip install ruff','ruff check .','ruff format .','pip install mypy','mypy .','pip install pytest','pytest','pytest -v','pytest -x (stop on first fail)','pytest --cov=src'],'Build & Publish':['pip install build','python -m build','pip install twine','twine upload dist/*','twine check dist/*','pip install setuptools wheel','python setup.py sdist bdist_wheel'],'Misc':['pip cache purge','pip config list','pip debug --verbose','python -c "import sys; print(sys.version)"','python -m site --user-site','pip install ipython','pip install jupyter','jupyter notebook','python -m http.server 8000']};
p=document.createElement('div');p.id='pip-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
this.style.color=\'\',600)" style="font-family:monospace;font-size:12px;padding:3px 8px;margin:2px 0;background:var(--bg-surface);border-radius:4px;cursor:pointer;color:var(--text-primary)">'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskDailyGoals(){
let p=document.getElementById('dailygoals-panel');if(p)p.remove();
const today=new Date().toISOString().split('T')[0];
if(!S._dailyGoals)S._dailyGoals={};
if(!S._dailyGoals[today])S._dailyGoals[today]=[];
p=document.createElement('div');p.id='dailygoals-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:440px;width:90vw;max-height:80vh;overflow-y:auto';
window._renderDailyGoals=function(){
const goals=S._dailyGoals[today]||[];
const done=goals.filter(g=>g.done).length;
let h='Daily Goals
'+new Date().toLocaleDateString('en',{weekday:'long',month:'short',day:'numeric'})+'
× ';
h+='';
h+=' '+done+'/'+goals.length+' completed
';
goals.forEach((g,i)=>{
h+='';
h+=' ';
h+=''+esc(g.text)+' ';
h+='× ';
h+='
';
});
h+='Add
';
document.getElementById('dailygoals-panel').innerHTML=h;
};
window._addGoal=function(){const input=document.getElementById('goal-input');if(!input||!input.value.trim())return;S._dailyGoals[today].push({text:input.value.trim(),done:false});save();window._renderDailyGoals();};
window._toggleGoal=function(i){S._dailyGoals[today][i].done=!S._dailyGoals[today][i].done;save();window._renderDailyGoals();};
window._deleteGoal=function(i){S._dailyGoals[today].splice(i,1);save();window._renderDailyGoals();};
document.body.appendChild(p);
window._renderDailyGoals();
}
function showQuickTextCounter(){
let w=document.getElementById('textcount-widget');if(w)w.remove();
w=document.createElement('div');w.id='textcount-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:320px';
w.innerHTML='
';
document.body.appendChild(w);
window._updateTextCount=function(){
const text=document.getElementById('textcount-input').value;
const chars=text.length;
const charsNoSpace=text.replace(/\s/g,'').length;
const words=text.trim()?text.trim().split(/\s+/).length:0;
const lines=text?text.split('\n').length:0;
const sentences=text.trim()?text.split(/[.!?]+/).filter(s=>s.trim()).length:0;
const paragraphs=text.trim()?text.split(/\n\n+/).filter(s=>s.trim()).length:0;
const readTime=Math.ceil(words/200);
const speakTime=Math.ceil(words/130);
const stats=[['Characters',chars],['No spaces',charsNoSpace],['Words',words],['Lines',lines],['Sentences',sentences],['Paragraphs',paragraphs],['Read time',readTime+'m'],['Speak time',speakTime+'m']];
const el=document.getElementById('textcount-stats');el.innerHTML='';
stats.forEach(([label,val])=>{el.innerHTML+=''+label+' '+val+'
';});
};
window._updateTextCount();
}
function showGoLangRef(){
let p=document.getElementById('go-ref-panel');if(p)p.remove();
const cmds={'Module & Build':['go mod init mymodule','go mod tidy','go mod download','go mod vendor','go mod graph','go build','go build -o myapp','go build -ldflags="-s -w"','go install','go run main.go','go run .','go clean -cache'],'Testing':['go test','go test ./...','go test -v','go test -run TestName','go test -count=1','go test -race','go test -cover','go test -coverprofile=coverage.out','go tool cover -html=coverage.out','go test -bench=.','go test -benchmem'],'Tools':['go fmt ./...','go vet ./...','gofmt -s -w .','go doc package','go doc -all package','golangci-lint run','go generate ./...','go tool pprof','go tool trace','go version','go env'],'Dependencies':['go get package@latest','go get package@v1.2.3','go get -u ./...','go list -m all','go list -m -u all','go list -m -json all','go work init','go work use ./module'],'Cross Compile':['GOOS=linux GOARCH=amd64 go build','GOOS=darwin GOARCH=arm64 go build','GOOS=windows GOARCH=amd64 go build','go tool dist list','CGO_ENABLED=0 go build']};
p=document.createElement('div');p.id='go-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
this.style.color=\'\',600)" style="font-family:monospace;font-size:12px;padding:3px 8px;margin:2px 0;background:var(--bg-surface);border-radius:4px;cursor:pointer;color:var(--text-primary)">'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskRetroBoard(){
let p=document.getElementById('retro-panel');if(p)p.remove();
const today=new Date().toISOString().split('T')[0];
if(!S._retroBoards)S._retroBoards={};
if(!S._retroBoards[today])S._retroBoards[today]={good:[],improve:[],action:[]};
p=document.createElement('div');p.id='retro-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
window._renderRetro=function(){
const board=S._retroBoards[today];
let h='';
h+=''+new Date().toLocaleDateString('en',{weekday:'long',month:'long',day:'numeric',year:'numeric'})+'
';
h+='';
const cols=[{key:'good',label:'Went Well',color:'#4ade80',icon:'+'},{key:'improve',label:'To Improve',color:'#fbbf24',icon:'!'},{key:'action',label:'Action Items',color:'#60a5fa',icon:'>'}];
cols.forEach(col=>{
h+='
';
h+='
'+col.label+'
';
board[col.key].forEach((item,i)=>{
h+='
'+esc(item)+' ×
';
});
h+='
';
h+='
';
});
h+='
';
document.getElementById('retro-panel').innerHTML=h;
};
window._addRetroItem=function(col,text){if(!text.trim())return;S._retroBoards[today][col].push(text.trim());save();window._renderRetro();};
window._removeRetroItem=function(col,i){S._retroBoards[today][col].splice(i,1);save();window._renderRetro();};
window._copyRetro=function(){const b=S._retroBoards[today];let md='# Retro - '+today+'\n\n## Went Well\n'+b.good.map(i=>'- '+i).join('\n')+'\n\n## To Improve\n'+b.improve.map(i=>'- '+i).join('\n')+'\n\n## Action Items\n'+b.action.map(i=>'- '+i).join('\n');navigator.clipboard.writeText(md);};
document.body.appendChild(p);
window._renderRetro();
}
function showQuickAspectRatioCalc(){
let w=document.getElementById('aspect-widget');if(w)w.remove();
w=document.createElement('div');w.id='aspect-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:280px';
w.innerHTML='
Common ratios:
';
document.body.appendChild(w);
const presets=[{label:'16:9',w:1920,h:1080},{label:'4:3',w:1024,h:768},{label:'21:9',w:2560,h:1080},{label:'1:1',w:1080,h:1080},{label:'9:16',w:1080,h:1920},{label:'3:2',w:1500,h:1000}];
const pe=document.getElementById('ar-presets');
presets.forEach(p=>{pe.innerHTML+=''+p.label+' ';});
window._calcAR=function(){
const w=parseInt(document.getElementById('ar-w').value)||1;const h=parseInt(document.getElementById('ar-h').value)||1;
const gcd=function(a,b){return b?gcd(b,a%b):a;};const g=gcd(w,h);
const ratio=(w/g)+':'+(h/g);const decimal=(w/h).toFixed(4);
document.getElementById('ar-result').innerHTML=''+ratio+'
'+decimal+' | '+w+'x'+h+'
';
};
window._calcAR();
}
function showJavaGradleRef(){
let p=document.getElementById('gradle-ref-panel');if(p)p.remove();
const cmds={'Build & Run':['gradle build','gradle build -x test','gradle clean','gradle clean build','gradle run','gradle bootRun','gradle jar','gradle bootJar','gradle assemble','gradle classes'],'Testing':['gradle test','gradle test --tests MyTest','gradle test --info','gradle test --rerun-tasks','gradle jacocoTestReport','gradle check'],'Dependencies':['gradle dependencies','gradle dependencies --configuration runtimeClasspath','gradle dependencyInsight --dependency lib','gradle refreshDependencies','gradle buildEnvironment'],'Tasks & Info':['gradle tasks','gradle tasks --all','gradle properties','gradle projects','gradle help --task build','gradle --version','gradle --status','gradle --stop'],'Wrapper':['gradle wrapper','gradle wrapper --gradle-version 8.5','./gradlew build','./gradlew bootRun','./gradlew test','chmod +x gradlew'],'Maven (mvn)':['mvn clean install','mvn clean package','mvn test','mvn compile','mvn dependency:tree','mvn spring-boot:run','mvn versions:display-dependency-updates','mvn -pl module -am install']};
p=document.createElement('div');p.id='gradle-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='Java / Gradle / Maven Reference
× ';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
this.style.color=\'\',600)" style="font-family:monospace;font-size:12px;padding:3px 8px;margin:2px 0;background:var(--bg-surface);border-radius:4px;cursor:pointer;color:var(--text-primary)">'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskMoodTracker(){
let p=document.getElementById('mood-panel');if(p)p.remove();
if(!S._moodLog)S._moodLog=[];
p=document.createElement('div');p.id='mood-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:500px;width:90vw;max-height:80vh;overflow-y:auto';
const moods=[{level:5,label:'Great',color:'#4ade80'},{level:4,label:'Good',color:'#a3e635'},{level:3,label:'Okay',color:'#fbbf24'},{level:2,label:'Low',color:'#fb923c'},{level:1,label:'Rough',color:'#f87171'}];
window._renderMood=function(){
const today=new Date().toISOString().split('T')[0];
const todayEntry=S._moodLog.find(m=>m.date===today);
let h='';
h+='How are you feeling today?
';
h+='';
moods.forEach(m=>{
const selected=todayEntry&&todayEntry.level===m.level;
h+='
'+['','(',':|',':|',':)','XD'][m.level]+'
'+m.label+'
';
});
h+='
';
if(todayEntry&&todayEntry.note){h+='Today\'s note:
'+esc(todayEntry.note)+'
';}
h+=' ';
const last7=S._moodLog.slice(-7);
if(last7.length>0){
h+='Last 7 entries
';
const w2=300,ht=60;
h+='';
let path='M';
last7.forEach((entry,i)=>{const x=(i/(Math.max(last7.length-1,1)))*w2;const y=ht-((entry.level-1)/4)*ht;path+=(i===0?'':' L')+x.toFixed(1)+' '+y.toFixed(1);const mc=moods.find(m=>m.level===entry.level);h+=' ';h+=''+entry.date.slice(5)+' ';});
h+=' ';
h+=' ';
}
document.getElementById('mood-panel').innerHTML=h;
};
window._logMood=function(level){
const today=new Date().toISOString().split('T')[0];
const existing=S._moodLog.findIndex(m=>m.date===today);
if(existing>=0)S._moodLog[existing].level=level;
else S._moodLog.push({date:today,level,note:''});
save();window._renderMood();
};
window._saveMoodNote=function(){
const today=new Date().toISOString().split('T')[0];
const note=document.getElementById('mood-note').value.trim();
const existing=S._moodLog.findIndex(m=>m.date===today);
if(existing>=0)S._moodLog[existing].note=note;
else S._moodLog.push({date:today,level:3,note});
save();window._renderMood();
};
document.body.appendChild(p);
window._renderMood();
}
function showQuickPomodoroSimple(){
let w=document.getElementById('pom-simple-widget');if(w)w.remove();
w=document.createElement('div');w.id='pom-simple-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:240px';
w.innerHTML='25:00
Work Session
Sessions: 0
Start Reset Skip
';
document.body.appendChild(w);
window._pomState2='work';window._pomTime2=25*60;window._pomSessions2=0;window._pomRunning2=false;window._pomInterval2=null;
window._pomUpdate2=function(){const m=Math.floor(window._pomTime2/60);const s=window._pomTime2%60;document.getElementById('pom-display2').textContent=String(m).padStart(2,'0')+':'+String(s).padStart(2,'0');document.getElementById('pom-display2').style.color=window._pomState2==='work'?'var(--text-primary)':'#4ade80';document.getElementById('pom-label2').textContent=window._pomState2==='work'?'Work Session':'Break';document.getElementById('pom-count2').textContent='Sessions: '+window._pomSessions2;};
window._pomStart2=function(){if(window._pomRunning2){clearInterval(window._pomInterval2);window._pomRunning2=false;document.getElementById('pom-btn2').textContent='Start';return;}window._pomRunning2=true;document.getElementById('pom-btn2').textContent='Pause';window._pomInterval2=setInterval(()=>{window._pomTime2--;if(window._pomTime2<=0){clearInterval(window._pomInterval2);window._pomRunning2=false;document.getElementById('pom-btn2').textContent='Start';if(window._pomState2==='work'){window._pomSessions2++;window._pomState2='break';window._pomTime2=5*60;}else{window._pomState2='work';window._pomTime2=25*60;}window._pomUpdate2();}else window._pomUpdate2();},1000);};
window._pomReset2=function(){if(window._pomInterval2)clearInterval(window._pomInterval2);window._pomRunning2=false;window._pomState2='work';window._pomTime2=25*60;document.getElementById('pom-btn2').textContent='Start';window._pomUpdate2();};
window._pomSkip2=function(){if(window._pomInterval2)clearInterval(window._pomInterval2);window._pomRunning2=false;if(window._pomState2==='work'){window._pomSessions2++;window._pomState2='break';window._pomTime2=5*60;}else{window._pomState2='work';window._pomTime2=25*60;}document.getElementById('pom-btn2').textContent='Start';window._pomUpdate2();};
window._pomUpdate2();
}
function showCurlRef(){
let p=document.getElementById('curl-ref-panel');if(p)p.remove();
const cmds={'Basic Requests':['curl https://example.com','curl -o file.html https://example.com','curl -O https://example.com/file.zip','curl -L https://short.url (follow redirects)','curl -I https://example.com (headers only)','curl -v https://example.com (verbose)','curl -s https://example.com (silent)','curl -w "%{http_code}" https://example.com'],'POST & Data':['curl -X POST https://api.example.com/data','curl -d "key=value" https://api.example.com','curl -d @data.json https://api.example.com','curl -X POST -H "Content-Type: application/json" -d \'{"key":"val"}\' URL','curl -F "file=@photo.jpg" https://upload.example.com','curl -X PUT -d "data" https://api.example.com/1','curl -X DELETE https://api.example.com/1','curl -X PATCH -d \'{"status":"done"}\' URL'],'Headers & Auth':['curl -H "Authorization: Bearer TOKEN" URL','curl -H "Content-Type: application/json" URL','curl -H "Accept: application/json" URL','curl -u user:pass https://api.example.com','curl --cookie "name=value" URL','curl --cookie-jar cookies.txt URL','curl -b cookies.txt URL','curl -H "X-Custom-Header: value" URL'],'Advanced':['curl --connect-timeout 5 URL','curl --max-time 30 URL','curl -x http://proxy:8080 URL','curl --retry 3 URL','curl -k https://self-signed.example.com (insecure)','curl --compressed URL','curl -C - -O URL (resume download)','curl --rate 10/m URL (rate limit)'],'Debug & Test':['curl -w "\\nTime: %{time_total}s\\nSize: %{size_download}b\\n" URL','curl -o /dev/null -s -w "%{http_code}" URL','curl --resolve example.com:443:1.2.3.4 https://example.com','curl --trace-ascii trace.txt URL','curl -D headers.txt URL']};
p=document.createElement('div');p.id='curl-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskHabitTracker(){
let p=document.getElementById('habit-panel');if(p)p.remove();
if(!S._habits)S._habits=[];
p=document.createElement('div');p.id='habit-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:600px;width:90vw;max-height:80vh;overflow-y:auto';
window._renderHabits=function(){
const today=new Date().toISOString().split('T')[0];
const days=[];for(let i=6;i>=0;i--){const d=new Date();d.setDate(d.getDate()-i);days.push(d.toISOString().split('T')[0]);}
let h='';
h+='';
h+='
';
days.forEach(d=>{const dt=new Date(d+'T12:00:00');h+='
'+dt.toLocaleDateString('en',{weekday:'short'}).slice(0,2)+' '+dt.getDate()+'
';});
h+='
';
S._habits.forEach((habit,hi)=>{
h+='
'+esc(habit.name)+'
';
days.forEach(d=>{
const done=habit.log&&habit.log.includes(d);
h+='
';
});
h+='
× ';
});
h+='
';
h+='Add
';
if(S._habits.length>0){
h+='';
S._habits.forEach(hab=>{const streak=window._calcStreak(hab);if(streak>0)h+=''+esc(hab.name)+': '+streak+' day streak ';});
h+='
';
}
document.getElementById('habit-panel').innerHTML=h;
};
window._addHabit=function(){const input=document.getElementById('habit-input');if(!input||!input.value.trim())return;S._habits.push({name:input.value.trim(),log:[]});save();window._renderHabits();};
window._toggleHabit=function(hi,date){if(!S._habits[hi].log)S._habits[hi].log=[];const idx=S._habits[hi].log.indexOf(date);if(idx>=0)S._habits[hi].log.splice(idx,1);else S._habits[hi].log.push(date);save();window._renderHabits();};
window._deleteHabit=function(hi){S._habits.splice(hi,1);save();window._renderHabits();};
window._calcStreak=function(habit){if(!habit.log||!habit.log.length)return 0;let streak=0;const today=new Date();for(let i=0;i<30;i++){const d=new Date(today);d.setDate(d.getDate()-i);const ds=d.toISOString().split('T')[0];if(habit.log.includes(ds))streak++;else break;}return streak;};
document.body.appendChild(p);
window._renderHabits();
}
function showQuickCronBuilder(){
let w=document.getElementById('cron-widget');if(w)w.remove();
w=document.createElement('div');w.id='cron-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:340px';
const fields=[{label:'Minute',id:'cron-min',ph:'0-59, */5'},{label:'Hour',id:'cron-hour',ph:'0-23, */2'},{label:'Day',id:'cron-day',ph:'1-31, *'},{label:'Month',id:'cron-month',ph:'1-12, *'},{label:'Weekday',id:'cron-dow',ph:'0-6, *'}];
let fh='';
fh+='';
fields.forEach(f=>{fh+='
'+f.label+'
';});
fh+='
';
fh+='
';
fh+='
';
fh+='Presets:
';
const presets=[{label:'Every min','v':['*','*','*','*','*']},{label:'Hourly','v':['0','*','*','*','*']},{label:'Daily 9am','v':['0','9','*','*','*']},{label:'Weekly Mon','v':['0','9','*','*','1']},{label:'Monthly 1st','v':['0','0','1','*','*']},{label:'Every 5min','v':['*/5','*','*','*','*']}];
presets.forEach(pr=>{fh+='document.getElementById(ids[i]).value=v);window._buildCron()" style="background:var(--bg-surface);color:var(--text-primary);border:1px solid var(--border);border-radius:4px;padding:3px 6px;font-size:9px;cursor:pointer">'+pr.label+' ';});
fh+='
';
w.innerHTML=fh;document.body.appendChild(w);
window._buildCron=function(){
const parts=['cron-min','cron-hour','cron-day','cron-month','cron-dow'].map(id=>document.getElementById(id).value||'*');
const expr=parts.join(' ');
document.getElementById('cron-result').textContent=expr;
let desc='Runs ';
if(parts[0]==='*')desc+='every minute';else if(parts[0].startsWith('*/'))desc+='every '+parts[0].slice(2)+' minutes';else desc+='at minute '+parts[0];
if(parts[1]!=='*'){if(parts[1].startsWith('*/'))desc+=', every '+parts[1].slice(2)+' hours';else desc+=', at '+parts[1]+':00';}
document.getElementById('cron-desc').textContent=desc;
};
window._buildCron();
}
function showSQLiteRef(){
let p=document.getElementById('sqlite-ref-panel');if(p)p.remove();
const cmds={'Database':['sqlite3 mydb.db','sqlite3 :memory:','.open mydb.db','.databases','.tables','.schema tablename','.quit','.exit','.help','.mode column','.headers on','.mode csv'],'Table Operations':['CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT UNIQUE);','ALTER TABLE users ADD COLUMN age INTEGER;','ALTER TABLE users RENAME TO customers;','DROP TABLE IF EXISTS users;','CREATE INDEX idx_email ON users(email);','VACUUM;','ANALYZE;'],'CRUD':['INSERT INTO users (name, email) VALUES (?, ?);','SELECT * FROM users;','SELECT * FROM users WHERE id = ?;','SELECT name, email FROM users ORDER BY name;','SELECT * FROM users LIMIT 10 OFFSET 20;','UPDATE users SET name = ? WHERE id = ?;','DELETE FROM users WHERE id = ?;','SELECT COUNT(*) FROM users;'],'Joins & Aggregates':['SELECT u.name, o.total FROM users u JOIN orders o ON u.id = o.user_id;','SELECT status, COUNT(*) FROM tasks GROUP BY status;','SELECT project, AVG(hours) FROM tasks GROUP BY project HAVING AVG(hours) > 2;','SELECT DISTINCT category FROM items;','SELECT * FROM t1 UNION SELECT * FROM t2;'],'Backup & Import':['.dump > backup.sql','.read backup.sql','.import data.csv tablename','.output result.csv','SELECT * FROM users; .output stdout','.backup mydb.db','ATTACH DATABASE "other.db" AS other;']};
p=document.createElement('div');p.id='sqlite-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskKanbanMetrics(){
let p=document.getElementById('kanban-metrics-panel');if(p)p.remove();
const tasks=(S.tasks||[]);
const statuses=['backlog','todo','in-progress','review','done'];
const statusCounts={};statuses.forEach(s=>statusCounts[s]=0);
tasks.forEach(t=>{const s=t.status||'todo';statusCounts[s]=(statusCounts[s]||0)+1;});
const wip=statusCounts['in-progress']||0;
const doneTasks=tasks.filter(t=>t.status==='done'&&t.completedAt&&t.created);
let avgCycleTime=0;
if(doneTasks.length>0){const cycleTimes=doneTasks.map(t=>{const start=new Date(t.created);const end=new Date(t.completedAt);return(end-start)/(1000*60*60*24);}).filter(d=>d>=0&&d<365);if(cycleTimes.length>0)avgCycleTime=(cycleTimes.reduce((s,v)=>s+v,0)/cycleTimes.length).toFixed(1);}
const now=new Date();const weekAgo=new Date(now.getTime()-7*24*60*60*1000);
const weeklyThroughput=tasks.filter(t=>t.status==='done'&&new Date(t.completedAt||'')>=weekAgo).length;
p=document.createElement('div');p.id='kanban-metrics-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:520px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
h+='';
h+='
';
h+='
'+avgCycleTime+'
Avg Cycle (days)
';
h+='
'+weeklyThroughput+'
Weekly Throughput
';
h+='
';
h+='Status Distribution
';
const maxCount=Math.max(...Object.values(statusCounts),1);
const statusColors={'backlog':'#6b7280','todo':'#60a5fa','in-progress':'#fbbf24','review':'#a78bfa','done':'#4ade80'};
statuses.forEach(s=>{
const count=statusCounts[s]||0;
h+='';
});
if(wip>5)h+='WIP limit exceeded! Consider finishing in-progress tasks before starting new ones.
';
p.innerHTML=h;document.body.appendChild(p);
}
function showQuickIpSubnetCalc(){
let w=document.getElementById('subnet-widget');if(w)w.remove();
w=document.createElement('div');w.id='subnet-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:320px';
w.innerHTML='/
Calculate
';
document.body.appendChild(w);
window._calcSubnet=function(){
const ip=document.getElementById('subnet-ip').value.trim();const cidr=parseInt(document.getElementById('subnet-cidr').value)||24;
const parts=ip.split('.').map(Number);if(parts.length!==4||parts.some(p=>isNaN(p)||p<0||p>255)){document.getElementById('subnet-result').innerHTML='Invalid IP
';return;}
const ipNum=(parts[0]<<24)+(parts[1]<<16)+(parts[2]<<8)+parts[3];
const mask=cidr===0?0:(0xFFFFFFFF<<(32-cidr))>>>0;
const network=(ipNum&mask)>>>0;const broadcast=(network|(~mask>>>0))>>>0;
const first=(network+1)>>>0;const last=(broadcast-1)>>>0;
const hosts=cidr>=31?Math.pow(2,32-cidr):Math.pow(2,32-cidr)-2;
const toIP=n=>[(n>>>24)&255,(n>>>16)&255,(n>>>8)&255,n&255].join('.');
const results=[['Network',toIP(network)],['Broadcast',toIP(broadcast)],['First Host',toIP(first)],['Last Host',toIP(last)],['Subnet Mask',toIP(mask)],['Hosts',hosts.toLocaleString()],['CIDR','/'+cidr],['Class',parts[0]<128?'A':parts[0]<192?'B':parts[0]<224?'C':'D/E']];
const el=document.getElementById('subnet-result');el.innerHTML='';
results.forEach(([label,val])=>{el.innerHTML+='';});
};
window._calcSubnet();
}
function showGitAdvancedRef(){
let p=document.getElementById('git-adv-ref-panel');if(p)p.remove();
const cmds={'Rebase':['git rebase main','git rebase --onto main feature old-feature','git rebase --abort','git rebase --continue','git rebase --skip','git pull --rebase'],'Cherry-pick':['git cherry-pick abc123','git cherry-pick abc123..def456','git cherry-pick --no-commit abc123','git cherry-pick --abort','git cherry-pick --continue'],'Stash':['git stash','git stash push -m "description"','git stash list','git stash show -p stash@{0}','git stash pop','git stash pop stash@{1}','git stash apply','git stash drop stash@{0}','git stash clear','git stash branch new-branch stash@{0}'],'Bisect':['git bisect start','git bisect bad','git bisect good abc123','git bisect reset','git bisect run npm test','git bisect log','git bisect visualize'],'Reset & Restore':['git reset --soft HEAD~1','git reset --mixed HEAD~1','git reset HEAD file.txt','git restore file.txt','git restore --staged file.txt','git restore --source=HEAD~3 file.txt','git checkout -- file.txt'],'Reflog & Recovery':['git reflog','git reflog show --date=iso','git checkout HEAD@{2}','git branch recovered HEAD@{5}','git fsck --lost-found'],'Advanced Log':['git log --oneline --graph --all','git log --author="name"','git log --since="2 weeks ago"','git log --stat','git log -p file.txt','git log --follow file.txt','git shortlog -sn','git blame file.txt','git show abc123'],'Worktree & Submodules':['git worktree add ../feature-branch feature','git worktree list','git worktree remove ../feature-branch','git submodule add URL path','git submodule update --init --recursive','git submodule foreach git pull']};
p=document.createElement('div');p.id='git-adv-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskSprintPlanner(){
let p=document.getElementById('sprint-panel');if(p)p.remove();
const tasks=(S.tasks||[]).filter(t=>t.status!=='done');
if(!S._sprints)S._sprints=[];
p=document.createElement('div');p.id='sprint-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:600px;width:90vw;max-height:80vh;overflow-y:auto';
window._renderSprint=function(){
const currentSprint=S._sprints.length>0?S._sprints[S._sprints.length-1]:null;
let h='';
if(!currentSprint){
h+='';
}else{
const sprintTasks=tasks.filter(t=>currentSprint.taskIds&¤tSprint.taskIds.includes(t.id));
const done=sprintTasks.filter(t=>t.status==='done').length;
const startDate=new Date(currentSprint.start);const endDate=new Date(startDate);endDate.setDate(endDate.getDate()+currentSprint.days);
const daysLeft=Math.max(0,Math.ceil((endDate-new Date())/(1000*60*60*1000*24)));
h+=''+esc(currentSprint.name)+' '+daysLeft+' days left
';
h+='';
h+=''+done+'/'+sprintTasks.length+' tasks completed
';
sprintTasks.forEach(t=>{
h+='';
});
const available=tasks.filter(t=>!currentSprint.taskIds||!currentSprint.taskIds.includes(t.id));
if(available.length>0){
h+='Add tasks to sprint:
';
available.slice(0,8).forEach(t=>{
h+='+ '+esc(t.title)+'
';
});
}
h+='End Sprint ';
}
document.getElementById('sprint-panel').innerHTML=h;
};
window._createSprint=function(){const name=document.getElementById('sprint-name').value||'Sprint';const days=parseInt(document.getElementById('sprint-days').value)||7;S._sprints.push({name,days,start:new Date().toISOString(),taskIds:[]});save();window._renderSprint();};
window._addToSprint=function(id){const s=S._sprints[S._sprints.length-1];if(!s.taskIds)s.taskIds=[];s.taskIds.push(id);save();window._renderSprint();};
window._removeFromSprint=function(id){const s=S._sprints[S._sprints.length-1];s.taskIds=s.taskIds.filter(t=>t!==id);save();window._renderSprint();};
window._endSprint=function(){save();window._renderSprint();};
document.body.appendChild(p);
window._renderSprint();
}
function showQuickQRCodeGen(){
let w=document.getElementById('qrgen-widget');if(w)w.remove();
w=document.createElement('div');w.id='qrgen-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:280px';
w.innerHTML='Generate
';
document.body.appendChild(w);
window._genQR=function(){
const text=document.getElementById('qr-input').value.trim();if(!text)return;
const url='https://api.qrserver.com/v1/create-qr-code/?size=200x200&data='+encodeURIComponent(text);
document.getElementById('qr-output').innerHTML='Right-click to save image
';
};
window._genQR();
}
function showYarnRef(){
let p=document.getElementById('yarn-ref-panel');if(p)p.remove();
const cmds={'Yarn (v1/Classic)':['yarn init','yarn install','yarn add package','yarn add -D package','yarn remove package','yarn upgrade','yarn upgrade-interactive','yarn list','yarn info package','yarn why package','yarn cache clean'],'Yarn (v2+/Berry)':['yarn set version stable','yarn dlx create-next-app','yarn add package','yarn up package','yarn plugin import typescript','yarn workspaces list','yarn workspaces foreach run build','yarn dedupe','yarn constraints'],'pnpm':['pnpm init','pnpm install','pnpm add package','pnpm add -D package','pnpm remove package','pnpm update','pnpm list','pnpm why package','pnpm store prune','pnpm exec command','pnpm dlx create-vite'],'pnpm Workspaces':['pnpm -r run build','pnpm --filter package-name run test','pnpm --filter "./packages/**" run lint','pnpm -r exec -- rm -rf node_modules','pnpm deploy --filter package-name'],'Common Scripts':['yarn/pnpm start','yarn/pnpm test','yarn/pnpm run build','yarn/pnpm run dev','yarn/pnpm run lint','yarn/pnpm run format','yarn/pnpm run typecheck']};
p=document.createElement('div');p.id='yarn-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskTimeboxPlanner(){
let p=document.getElementById('timebox-panel');if(p)p.remove();
if(!S._timeboxes)S._timeboxes=[];
p=document.createElement('div');p.id='timebox-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:500px;width:90vw;max-height:80vh;overflow-y:auto';
window._renderTimeboxes=function(){
const today=new Date().toISOString().split('T')[0];
const todayBoxes=S._timeboxes.filter(b=>b.date===today);
let h='';
h+=''+new Date().toLocaleDateString('en',{weekday:'long',month:'long',day:'numeric'})+'
';
const totalMin=todayBoxes.reduce((s,b)=>s+b.minutes,0);
h+='Total planned: '+(totalMin/60).toFixed(1)+'h ('+totalMin+'min)
';
todayBoxes.forEach((box,i)=>{
h+='';
h+='
';
h+='
';
h+='
'+box.minutes+'m ';
h+='
× ';
h+='
';
});
h+='Add
';
document.getElementById('timebox-panel').innerHTML=h;
};
window._addTimebox=function(){const task=document.getElementById('tb-task').value.trim();const min=parseInt(document.getElementById('tb-min').value)||30;if(!task)return;S._timeboxes.push({task,minutes:min,done:false,date:new Date().toISOString().split('T')[0]});save();window._renderTimeboxes();};
window._toggleTimebox=function(i){const today=new Date().toISOString().split('T')[0];const todayBoxes=S._timeboxes.filter(b=>b.date===today);const globalIdx=S._timeboxes.indexOf(todayBoxes[i]);if(globalIdx>=0){S._timeboxes[globalIdx].done=!S._timeboxes[globalIdx].done;save();window._renderTimeboxes();}};
window._deleteTimebox=function(i){const today=new Date().toISOString().split('T')[0];const todayBoxes=S._timeboxes.filter(b=>b.date===today);const globalIdx=S._timeboxes.indexOf(todayBoxes[i]);if(globalIdx>=0){S._timeboxes.splice(globalIdx,1);save();window._renderTimeboxes();}};
document.body.appendChild(p);
window._renderTimeboxes();
}
function showQuickEmojiSearch(){
let w=document.getElementById('emoji-widget');if(w)w.remove();
w=document.createElement('div');w.id='emoji-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:300px';
const emojis=[['Smileys','😀😃😄😁😆😅🤣😂🙂🙃😉😊😇🥰😍🤩😘😗😚😋😛😜🤪😝🤑🤗🤭🤫🤔🤐🤨😐😑😶😏😒🙄😬🤥😌😔😪🤤😴😷🤒🤕🤢🤮🤧🥵🥶🥴😵🤯🤠'],['Hands','👋🤚🖐✋🖖👌🤌🤏✌🤞🤟🤘🤙👈👉👆🖕👇☝👍👎✊👊🤛🤜👏🙌👐🤲🤝🙏'],['Hearts','❤🧡💛💚💙💜🖤🤍🤎💔❣💕💞💓💗💖💘💝💟'],['Objects','⌚📱💻⌨🖥🖨🖱💿📀📷📹🎥📞☎📟📠📺📻🔋🔌💡🔦🕯🧯🛢💸💵💴💶💷🪙💰💳💎'],['Nature','🌞🌝🌙⭐🌟✨⚡🔥🌈☀🌤⛅🌥🌦🌧⛈🌩🌨❄☃⛄🌬💨🌪🌫🌊🌺🌸🏵🌹🌻🌼🌷'],['Food','🍏🍎🍐🍊🍋🍌🍉🍇🍓🫐🍑🥝🥑🍅🥦🥬🥒🌶🫑🌽🥕🧄🧅🥔🍞🥐🥖🧀🥚🍳🧈🥞🧇🍖🍗🥩🌭🍔🍟🍕'],['Flags','🏁🚩🎌🏴🏳🇺🇸🇬🇧🇫🇷🇩🇪🇪🇸🇮🇹🇯🇵🇨🇳🇰🇷🇧🇷🇲🇽🇦🇷🇨🇴🇻🇪']];
let eh='';
eh+=' ';
eh+='
';
eh+='
';
w.innerHTML=eh;document.body.appendChild(w);
window._emojiData=emojis;
window._filterEmojis=function(){
const q=(document.getElementById('emoji-search').value||'').toLowerCase();
const el=document.getElementById('emoji-grid');el.innerHTML='';
emojis.forEach(([cat,chars])=>{
if(q&&!cat.toLowerCase().includes(q))return;
el.innerHTML+=''+cat+'
';
const grid=document.createElement('div');grid.style.cssText='display:flex;flex-wrap:wrap;gap:2px';
[...chars].filter(c=>c.trim()).forEach(ch=>{
if(ch.codePointAt(0)<256)return;
const btn=document.createElement('span');btn.textContent=ch;btn.style.cssText='font-size:20px;cursor:pointer;padding:2px;border-radius:3px';
btn.onclick=()=>{navigator.clipboard.writeText(ch);document.getElementById('emoji-copied').textContent='Copied: '+ch;setTimeout(()=>{const e2=document.getElementById('emoji-copied');if(e2)e2.textContent='';},1000);};
btn.onmouseover=()=>btn.style.background='var(--bg-surface)';
btn.onmouseout=()=>btn.style.background='none';
grid.appendChild(btn);
});
el.appendChild(grid);
});
};
window._filterEmojis();
}
function showFFmpegRef(){
let p=document.getElementById('ffmpeg-ref-panel');if(p)p.remove();
const cmds={'Basic Conversion':['ffmpeg -i input.mp4 output.avi','ffmpeg -i input.mov -c:v libx264 output.mp4','ffmpeg -i input.mp4 -c:v libx265 output.mp4','ffmpeg -i input.webm output.mp4','ffmpeg -i input.mp4 -c copy output.mkv','ffmpeg -i input.mp4 -an output_noaudio.mp4','ffmpeg -i input.mp4 -vn output.mp3'],'Audio':['ffmpeg -i input.mp3 -b:a 192k output.mp3','ffmpeg -i input.wav output.mp3','ffmpeg -i input.mp4 -vn -acodec copy output.aac','ffmpeg -i input.mp4 -vn output.wav','ffmpeg -i input.m4a -c:a libmp3lame -q:a 2 output.mp3','ffmpeg -i input.mp3 -ss 00:00:30 -to 00:01:00 -c copy clip.mp3'],'Video Editing':['ffmpeg -i input.mp4 -ss 00:01:00 -to 00:02:00 -c copy clip.mp4','ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4','ffmpeg -i input.mp4 -vf "scale=-1:720" output.mp4','ffmpeg -i input.mp4 -r 30 output.mp4','ffmpeg -i input.mp4 -crf 23 output.mp4','ffmpeg -i input.mp4 -vf "crop=640:480:0:0" output.mp4','ffmpeg -i input.mp4 -vf "transpose=1" rotated.mp4','ffmpeg -i input.mp4 -vf "setpts=0.5*PTS" fast.mp4'],'Images & GIF':['ffmpeg -i input.mp4 -vf fps=1 frame_%04d.png','ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 thumb.jpg','ffmpeg -i input.mp4 -vf "fps=10,scale=320:-1" output.gif','ffmpeg -pattern_type glob -i "*.png" -r 24 output.mp4','ffmpeg -i input.mp4 -vf "palettegen" palette.png'],'Concat & Merge':['ffmpeg -f concat -i list.txt -c copy output.mp4','ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a aac output.mp4','ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex hstack side.mp4'],'Info & Stream':['ffprobe input.mp4','ffprobe -v error -show_format input.mp4','ffmpeg -i input.mp4 -f null - (validate)','ffmpeg -formats','ffmpeg -codecs','ffmpeg -encoders']};
p=document.createElement('div');p.id='ffmpeg-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskDecisionLog(){
let p=document.getElementById('decision-panel');if(p)p.remove();
if(!S._decisions)S._decisions=[];
p=document.createElement('div');p.id='decision-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:600px;width:90vw;max-height:80vh;overflow-y:auto';
window._renderDecisions=function(){
let h='';
h+=''+S._decisions.length+' decisions logged
';
S._decisions.slice().reverse().forEach((d,i)=>{
const idx=S._decisions.length-1-i;
const statusColor=d.status==='approved'?'#4ade80':d.status==='rejected'?'#f87171':d.status==='pending'?'#fbbf24':'#60a5fa';
h+='';
h+='
'+esc(d.title)+' ×
';
if(d.context)h+='
'+esc(d.context)+'
';
h+='
'+d.status+' '+new Date(d.date).toLocaleDateString()+'
';
h+='
';
});
h+='';
document.getElementById('decision-panel').innerHTML=h;
};
window._addDecision=function(){const title=document.getElementById('dec-title').value.trim();if(!title)return;const context=document.getElementById('dec-context').value.trim();const status=document.getElementById('dec-status').value;S._decisions.push({title,context,status,date:new Date().toISOString()});save();window._renderDecisions();};
window._deleteDecision=function(i){S._decisions.splice(i,1);save();window._renderDecisions();};
window._copyDecisions=function(){const md='# Decision Log\n\n'+S._decisions.map(d=>'## '+d.title+'\n- Status: '+d.status+'\n- Date: '+new Date(d.date).toLocaleDateString()+'\n'+(d.context?'- Context: '+d.context+'\n':'')).join('\n');navigator.clipboard.writeText(md);};
document.body.appendChild(p);
window._renderDecisions();
}
function showQuickGradientGen(){
let w=document.getElementById('gradient-widget');if(w)w.remove();
w=document.createElement('div');w.id='gradient-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:300px';
w.innerHTML='
90 135 180 45 Linear Radial
';
document.body.appendChild(w);
window._updateGradient=function(){
const c1=document.getElementById('grad-c1').value;const c2=document.getElementById('grad-c2').value;
const angle=document.getElementById('grad-angle').value;const type=document.getElementById('grad-type').value;
let css;
if(type==='linear')css='linear-gradient('+angle+'deg, '+c1+', '+c2+')';
else css='radial-gradient(circle, '+c1+', '+c2+')';
document.getElementById('grad-preview').style.background=css;
document.getElementById('grad-css').textContent='background: '+css+';';
};
window._updateGradient();
}
function showLinuxPermissionsRef(){
let p=document.getElementById('perms-ref-panel');if(p)p.remove();
const cmds={'chmod':['chmod 755 file','chmod 644 file','chmod 600 file','chmod 700 dir/','chmod +x script.sh','chmod -R 755 dir/','chmod u+x file','chmod g+rw file','chmod o-rwx file','chmod a+r file','chmod u=rwx,g=rx,o=r file'],'chown':['chown user file','chown user:group file','chown -R user:group dir/','chown --reference=ref_file target','chgrp group file','chgrp -R group dir/'],'Permission Numbers':['0 = ---','1 = --x','2 = -w-','3 = -wx','4 = r--','5 = r-x','6 = rw-','7 = rwx'],'Common Patterns':['755 = rwxr-xr-x (executables)','644 = rw-r--r-- (regular files)','600 = rw------- (private files)','700 = rwx------ (private dirs)','775 = rwxrwxr-x (shared dirs)','664 = rw-rw-r-- (shared files)','444 = r--r--r-- (read-only)','000 = --------- (no access)'],'Special':['chmod 4755 file (setuid)','chmod 2755 dir/ (setgid)','chmod 1777 dir/ (sticky bit)','umask 022','umask -S','stat -c "%a %U:%G %n" file','find . -perm 777','find . -not -perm 644 -type f'],'ACL':['getfacl file','setfacl -m u:user:rwx file','setfacl -m g:group:rx file','setfacl -x u:user file','setfacl -b file (remove all ACLs)','setfacl -R -m u:user:rx dir/']};
p=document.createElement('div');p.id='perms-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='Linux Permissions (chmod) Reference
× ';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskWinLog(){
let p=document.getElementById('winlog-panel');if(p)p.remove();
if(!S._winLog)S._winLog=[];
p=document.createElement('div');p.id='winlog-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:500px;width:90vw;max-height:80vh;overflow-y:auto';
window._renderWins=function(){
let h='';
h+='Celebrate your accomplishments. '+S._winLog.length+' wins logged.
';
S._winLog.slice().reverse().forEach((w2,i)=>{
const idx=S._winLog.length-1-i;
h+=''+esc(w2.text)+'
'+new Date(w2.date).toLocaleDateString('en',{weekday:'short',month:'short',day:'numeric'})+'
× ';
});
h+='Add
';
document.getElementById('winlog-panel').innerHTML=h;
};
window._addWin=function(){const input=document.getElementById('win-input');if(!input||!input.value.trim())return;S._winLog.push({text:input.value.trim(),date:new Date().toISOString()});save();window._renderWins();};
window._deleteWin=function(i){S._winLog.splice(i,1);save();window._renderWins();};
window._copyWins=function(){const md='# Win Log\n\n'+S._winLog.map(w2=>'- ['+new Date(w2.date).toLocaleDateString()+'] '+w2.text).join('\n');navigator.clipboard.writeText(md);};
document.body.appendChild(p);
window._renderWins();
}
function showQuickBrainDump(){
let w=document.getElementById('braindump-widget');if(w)w.remove();
if(!S._brainDumps)S._brainDumps=[];
w=document.createElement('div');w.id='braindump-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:340px';
w.innerHTML='Capture thoughts fast. Press Enter or click Save.
Save Save as Task Save as Content
';
document.body.appendChild(w);
window._renderBDRecent=function(){
const el=document.getElementById('bd-recent');el.innerHTML='';
S._brainDumps.slice(-5).reverse().forEach(d=>{el.innerHTML+=''+esc(d.text.substring(0,60))+' '+new Date(d.date).toLocaleTimeString()+'
';});
};
window._saveBrainDump=function(){const text=document.getElementById('bd-input').value.trim();if(!text)return;S._brainDumps.push({text,date:new Date().toISOString(),type:'thought'});save();document.getElementById('bd-input').value='';window._renderBDRecent();};
window._saveBrainDumpAsTask=function(){const text=document.getElementById('bd-input').value.trim();if(!text)return;if(!S.tasks)S.tasks=[];S.tasks.push({id:'t_'+Date.now(),title:text,status:'todo',priority:'p2',created:new Date().toISOString()});S._brainDumps.push({text,date:new Date().toISOString(),type:'task'});save();document.getElementById('bd-input').value='';window._renderBDRecent();};
window._saveBrainDumpAsContent=function(){const text=document.getElementById('bd-input').value.trim();if(!text)return;if(!S.content)S.content=[];S.content.push({id:'c_'+Date.now(),text,tags:['brain-dump'],created:new Date().toISOString()});S._brainDumps.push({text,date:new Date().toISOString(),type:'content'});save();document.getElementById('bd-input').value='';window._renderBDRecent();};
window._renderBDRecent();
}
function showSedAwkRef(){
let p=document.getElementById('sedawk-ref-panel');if(p)p.remove();
const cmds={'sed Basics':['sed "s/old/new/" file','sed "s/old/new/g" file','sed -i "s/old/new/g" file (in-place)','sed -n "5p" file (print line 5)','sed -n "5,10p" file (lines 5-10)','sed "3d" file (delete line 3)','sed "/pattern/d" file (delete matching)','sed "1i\\header" file (insert before line 1)','sed "$a\\footer" file (append after last)','sed -n "/start/,/end/p" file (range)'],'sed Advanced':['sed "s/[0-9]\\+/NUM/g" file','sed -E "s/(word1|word2)/REPLACED/g" file','sed "/^$/d" file (remove blank lines)','sed "s/^/ /" file (indent)','sed "s/\\t/ /g" file (tabs to spaces)','sed "N;s/\\n/ /" file (join pairs)','sed -e "s/a/A/" -e "s/b/B/" file','sed "y/abc/ABC/" file (transliterate)'],'awk Basics':['awk "{print}" file','awk "{print $1}" file (first field)','awk "{print $1, $3}" file','awk -F "," "{print $2}" file.csv','awk "{print NR, $0}" file (line numbers)','awk "/pattern/ {print}" file','awk "NR==5" file (line 5)','awk "NR>=5 && NR<=10" file'],'awk Processing':['awk "{sum+=$1} END {print sum}" file','awk "{sum+=$1; n++} END {print sum/n}" file','awk "{print length, $0}" file | sort -n','awk "!seen[$0]++" file (unique lines)','awk "{count[$1]++} END {for(k in count) print k, count[k]}" file','awk "BEGIN {OFS=","} {print $1,$2,$3}" file','awk "{gsub(/old/,"new"); print}" file','awk -v var="value" "{print var, $0}" file'],'Common Recipes':['awk -F: "{print $1}" /etc/passwd','ps aux | awk "{print $2, $11}"','df -h | awk "NR>1 {print $5, $6}"','cat access.log | awk "{print $1}" | sort | uniq -c | sort -rn','sed "s/\\r$//" file (dos2unix)','awk "{print $NF}" file (last field)','awk "length > 80" file (long lines)']};
p=document.createElement('div');p.id='sedawk-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskProjectSummary(){
let p=document.getElementById('projsummary-panel');if(p)p.remove();
const tasks=(S.tasks||[]);const projects=(S.projects||[]);const content=(S.content||[]);const docs=(S.writerDocs||[]);const links=(S.links||[]);
p=document.createElement('div');p.id='projsummary-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:650px;width:90vw;max-height:80vh;overflow-y:auto';
let h='Project Summary Report
Copy ×
';
let summaryMd='# Project Summary Report\n\n';
projects.forEach(proj=>{
const projTasks=tasks.filter(t=>(t.project||t.projectId)===proj.id);
const done=projTasks.filter(t=>t.status==='done').length;
const active=projTasks.filter(t=>t.status!=='done').length;
const overdue=projTasks.filter(t=>t.status!=='done'&&t.due&&new Date(t.due)(c.project||c.projectId)===proj.id).length;
const projDocs=docs.filter(d=>(d.project||d.projectId)===proj.id).length;
const projLinks=links.filter(l=>(l.project||l.projectId)===proj.id).length;
const pct=projTasks.length>0?Math.round(done/projTasks.length*100):0;
h+='';
h+='
'+esc(proj.name)+' '+pct+'%
';
h+='
';
h+='
';
h+='Tasks: '+done+'/'+projTasks.length+' ';
h+='Active: '+active+' ';
if(overdue>0)h+='Overdue: '+overdue+' ';
if(projContent>0)h+='Content: '+projContent+' ';
if(projDocs>0)h+='Docs: '+projDocs+' ';
if(projLinks>0)h+='Links: '+projLinks+' ';
h+='
';
summaryMd+='## '+proj.name+'\n- Progress: '+pct+'%\n- Tasks: '+done+'/'+projTasks.length+' ('+active+' active'+(overdue>0?', '+overdue+' overdue':'')+')\n\n';
});
h+='Total: '+tasks.length+' tasks | '+content.length+' content | '+docs.length+' docs | '+links.length+' links
';
summaryMd+='---\nTotal: '+tasks.length+' tasks, '+content.length+' content, '+docs.length+' docs, '+links.length+' links\n';
p.innerHTML=h;document.body.appendChild(p);
window._projSummaryMd=summaryMd;
window._copyProjSummary=function(){navigator.clipboard.writeText(window._projSummaryMd);};
}
function showQuickTableGen(){
let w=document.getElementById('tablegen-widget');if(w)w.remove();
w=document.createElement('div');w.id='tablegen-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:340px';
w.innerHTML='
Copy ';
document.body.appendChild(w);
window._genTable=function(format){
const rows=parseInt(document.getElementById('tbl-rows').value)||3;
const cols=parseInt(document.getElementById('tbl-cols').value)||3;
let result='';
if(format==='md'){
result+='| '+Array.from({length:cols},(_,i)=>'Header '+(i+1)).join(' | ')+' |\n';
result+='| '+Array.from({length:cols},()=>'---').join(' | ')+' |\n';
for(let r=0;r'Cell '+(r+1)+'-'+(c+1)).join(' | ')+' |\n';}
}else{
result+='\n \n \n';
for(let c=0;cHeader '+(c+1)+'\n';
result+=' \n \n \n';
for(let r=0;r\n';for(let c=0;cCell '+(r+1)+'-'+(c+1)+'\n';result+=' \n';}
result+=' \n
';
}
document.getElementById('tbl-output').textContent=result;
};
window._genTable('md');
}
function showTmuxRef(){
let p=document.getElementById('tmux-ref-panel');if(p)p.remove();
const cmds={'Sessions':['tmux new -s mysession','tmux ls','tmux attach -t mysession','tmux kill-session -t mysession','tmux rename-session -t old new','tmux switch -t mysession','tmux detach (Ctrl+B D)'],'Windows':['Ctrl+B C (new window)','Ctrl+B , (rename window)','Ctrl+B N (next window)','Ctrl+B P (previous window)','Ctrl+B 0-9 (select window)','Ctrl+B W (list windows)','Ctrl+B & (kill window)','tmux new-window -n name'],'Panes':['Ctrl+B % (split vertical)','Ctrl+B " (split horizontal)','Ctrl+B Arrow (navigate panes)','Ctrl+B O (next pane)','Ctrl+B Z (zoom pane)','Ctrl+B X (kill pane)','Ctrl+B { (move pane left)','Ctrl+B } (move pane right)','Ctrl+B Q (show pane numbers)','Ctrl+B Space (cycle layouts)'],'Copy Mode':['Ctrl+B [ (enter copy mode)','Space (start selection)','Enter (copy selection)','Ctrl+B ] (paste)','Q (exit copy mode)','/ (search forward)','? (search backward)','N (next match)'],'Config':['set -g mouse on','set -g default-terminal "screen-256color"','set -g history-limit 10000','set -g base-index 1','set -g pane-base-index 1','set -g status-style bg=black,fg=white','bind r source-file ~/.tmux.conf','tmux source-file ~/.tmux.conf']};
p=document.createElement('div');p.id='tmux-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskIdleDetector(){
let p=document.getElementById('idle-panel');if(p)p.remove();
const tasks=(S.tasks||[]).filter(t=>t.status!=='done');
const now=new Date();
const idle=tasks.filter(t=>{
const created=new Date(t.created||'');
const daysSinceCreated=(now-created)/(1000*60*60*24);
return daysSinceCreated>7&&t.status!=='in-progress'&&t.status!=='inprogress';
}).sort((a,b)=>new Date(a.created||'')-new Date(b.created||''));
p=document.createElement('div');p.id='idle-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:520px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
h+=''+idle.length+' tasks sitting idle for 7+ days
';
if(idle.length===0){h+='No idle tasks found. Everything is moving!
';}
idle.forEach(t=>{
const days=Math.floor((now-new Date(t.created||''))/(1000*60*60*24));
const color=days>30?'#f87171':days>14?'#fbbf24':'#60a5fa';
h+='';
h+='
'+esc(t.title)+'
'+t.status+' | Created '+days+' days ago
';
h+='
'+days+'d ';
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showQuickRandomPicker(){
let w=document.getElementById('picker-widget');if(w)w.remove();
w=document.createElement('div');w.id='picker-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:280px';
w.innerHTML='Pick Random
';
document.body.appendChild(w);
window._pickerHistory=[];
window._pickRandom=function(){
const items=document.getElementById('picker-items').value.split('\n').map(s=>s.trim()).filter(s=>s);
if(items.length===0)return;
const picked=items[Math.floor(Math.random()*items.length)];
document.getElementById('picker-result').textContent=picked;
window._pickerHistory.unshift(picked);
if(window._pickerHistory.length>5)window._pickerHistory.length=5;
document.getElementById('picker-history').textContent='History: '+window._pickerHistory.join(' | ');
};
}
function showVimRef(){
let p=document.getElementById('vim-ref-panel');if(p)p.remove();
const cmds={'Movement':['h/j/k/l (left/down/up/right)','w/W (next word)','b/B (back word)','e/E (end of word)','0 (line start)','$ (line end)','^ (first non-blank)','gg (file start)','G (file end)','Ctrl+D/U (half page down/up)','Ctrl+F/B (full page down/up)','{/} (paragraph up/down)','% (matching bracket)','f{char} (find char forward)','t{char} (till char forward)'],'Editing':['i (insert before)','I (insert at line start)','a (append after)','A (append at line end)','o (new line below)','O (new line above)','r (replace char)','R (replace mode)','x (delete char)','dd (delete line)','dw (delete word)','D (delete to end)','cc (change line)','cw (change word)','C (change to end)','J (join lines)','u (undo)','Ctrl+R (redo)','. (repeat last)'],'Visual & Select':['v (visual char)','V (visual line)','Ctrl+V (visual block)','y (yank/copy)','yy (yank line)','p (paste after)','P (paste before)','d (delete selected)','> (indent)','< (unindent)','= (auto-indent)'],'Search & Replace':['/{pattern} (search forward)','?{pattern} (search backward)','n/N (next/prev match)','* (search word under cursor)',':%s/old/new/g (replace all)',':%s/old/new/gc (replace with confirm)',':s/old/new/g (replace in line)'],'Files & Buffers':[':w (save)',':q (quit)',':wq (save & quit)',':q! (force quit)',':e file (open file)',':sp file (split horizontal)',':vsp file (split vertical)','Ctrl+W + h/j/k/l (switch splits)',':bn/:bp (next/prev buffer)',':ls (list buffers)',':tabnew file (new tab)','gt/gT (next/prev tab)'],'Macros & Registers':['q{a-z} (record macro)','@{a-z} (play macro)','@@ (replay last macro)','"{a-z}y (yank to register)','"{a-z}p (paste from register)',':reg (show registers)']};
p=document.createElement('div');p.id='vim-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskROI(){
let p=document.getElementById('roi-panel');if(p)p.remove();
const tasks=(S.tasks||[]);
const scored=tasks.filter(t=>t.status!=='done').map(t=>{
let impact=1;const pr=t.priority||'p2';
if(pr==='p0')impact=4;else if(pr==='p1')impact=3;else if(pr==='p2')impact=2;else impact=1;
let effort=2;
if(t.estimate){const m=t.estimate.match(/(\d+)\s*(h|m)/);if(m){const mins=m[2]==='h'?parseInt(m[1])*60:parseInt(m[1]);effort=mins<=30?1:mins<=120?2:mins<=480?3:4;}}
const roi=impact/effort;
return{...t,impact,effort,roi};
}).sort((a,b)=>b.roi-a.roi);
p=document.createElement('div');p.id='roi-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:550px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
h+='Impact (from priority) / Effort (from estimate) = ROI score. Higher = do first.
';
h+='';
scored.slice(0,15).forEach((t,i)=>{
const roiColor=t.roi>=2?'#4ade80':t.roi>=1?'#fbbf24':'#f87171';
h+='';
h+='
'+esc(t.title)+'
';
h+='
'+t.impact+'
';
h+='
'+t.effort+'
';
h+='
'+t.roi.toFixed(1)+'
';
h+='
';
});
if(scored.length===0)h+='No active tasks to analyze.
';
p.innerHTML=h;document.body.appendChild(p);
}
function showQuickWhiteNoise(){
let w=document.getElementById('whitenoise-widget');if(w)w.remove();
w=document.createElement('div');w.id='whitenoise-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:240px';
w.innerHTML='Stopped
Volume
White Pink Brown
Stop ';
document.body.appendChild(w);
window._noiseCtx=null;window._noiseNode=null;window._noiseGain=null;
window._startNoise=function(type){
window._stopNoise();
window._noiseCtx=new(window.AudioContext||window.webkitAudioContext)();
const bufferSize=2*window._noiseCtx.sampleRate;
const buffer=window._noiseCtx.createBuffer(1,bufferSize,window._noiseCtx.sampleRate);
const output=buffer.getChannelData(0);
if(type==='white'){for(let i=0;i{
h+=''+cat+'
';
list.forEach(c=>{const parts=c.split(' - ');h+='
this.style.color=\'\',600)" style="font-family:monospace;font-size:12px;padding:3px 8px;margin:2px 0;background:var(--bg-surface);border-radius:4px;cursor:pointer;color:var(--text-primary)">'+(parts[0]||'')+' '+(parts[1]?' '+parts[1]+' ':'')+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskPareto(){
let p=document.getElementById('pareto-panel');if(p)p.remove();
const tasks=(S.tasks||[]);const projects=(S.projects||[]);
const projCounts={};tasks.forEach(t=>{const pid=t.project||t.projectId||'unassigned';projCounts[pid]=(projCounts[pid]||0)+1;});
const sorted=Object.entries(projCounts).sort((a,b)=>b[1]-a[1]);
const total=sorted.reduce((s,[_,c])=>s+c,0);
let cumulative=0;
const paretoData=sorted.map(([pid,count])=>{cumulative+=count;const pct=(count/total*100).toFixed(1);const cumPct=(cumulative/total*100).toFixed(1);const proj=projects.find(pr=>pr.id===pid);return{name:proj?proj.name:pid,count,pct,cumPct};});
p=document.createElement('div');p.id='pareto-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:520px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
h+='Which projects consume most of your tasks?
';
const maxCount=paretoData.length>0?paretoData[0].count:1;
paretoData.forEach(d=>{
const is80=parseFloat(d.cumPct)<=80;
h+='';
h+='
';
h+='
'+d.count+' ('+d.pct+'%)
cum: '+d.cumPct+'%
';
h+='
';
});
if(paretoData.length===0)h+='No tasks to analyze.
';
p.innerHTML=h;document.body.appendChild(p);
}
function showQuickMathSolver(){
let w=document.getElementById('math-widget');if(w)w.remove();
w=document.createElement('div');w.id='math-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:300px';
w.innerHTML='
Supports: +, -, *, /, **, %, sqrt(), abs(), ceil(), floor(), round(), sin(), cos(), tan(), log(), PI, E
';
document.body.appendChild(w);
window._mathHistory=[];
window._evalMath=function(){
const expr=document.getElementById('math-input').value.trim();if(!expr){document.getElementById('math-result').textContent='';return;}
try{
const safe=expr.replace(/\bsqrt\b/g,'Math.sqrt').replace(/\babs\b/g,'Math.abs').replace(/\bceil\b/g,'Math.ceil').replace(/\bfloor\b/g,'Math.floor').replace(/\bround\b/g,'Math.round').replace(/\bsin\b/g,'Math.sin').replace(/\bcos\b/g,'Math.cos').replace(/\btan\b/g,'Math.tan').replace(/\blog\b/g,'Math.log').replace(/\bPI\b/g,'Math.PI').replace(/\bE\b/g,'Math.E');
if(/[^0-9+\-*/%().Math,sqrtabceifloorundsincogtanlgPIE\s]/g.test(safe.replace(/Math\.\w+/g,''))){document.getElementById('math-result').textContent='?';return;}
const result=Function('"use strict"; return ('+safe+')')();
document.getElementById('math-result').textContent=typeof result==='number'?result:'?';
}catch(e){document.getElementById('math-result').textContent='?';}
};
}
function showJqRef(){
let p=document.getElementById('jq-ref-panel');if(p)p.remove();
const cmds={'Basic':['jq . file.json (pretty print)','jq -r .name file.json (raw output)','jq -c . file.json (compact)','jq .key file.json','jq .key.nested file.json','jq .array[0] file.json','jq .array[-1] file.json','jq .array[2:5] file.json','jq length file.json','jq keys file.json','jq type file.json'],'Filters':['jq ".[] | .name" file.json','jq "[.[] | .name]" file.json','jq "map(.name)" file.json','jq "map(select(.age > 18))" file.json','jq "sort_by(.name)" file.json','jq "group_by(.category)" file.json','jq "unique_by(.id)" file.json','jq "flatten" file.json','jq "reverse" file.json','jq "limit(5; .[])" file.json'],'Transform':['jq "{name, age}" file.json','jq "{full_name: .name, years: .age}" file.json','jq ". + {new_key: \"value\"}" file.json','jq "del(.unwanted)" file.json','jq ".key |= . + 1" file.json','jq "to_entries" file.json','jq "from_entries" file.json','jq "with_entries(.key |= \"prefix_\" + .)" file.json'],'String & Math':['jq ".name | length" file.json','jq ".name | ascii_downcase" file.json','jq ".name | split(\" \")" file.json','jq ".items | add" file.json','jq "[.items[].price] | add" file.json','jq ".items | min_by(.price)" file.json','jq ".items | max_by(.price)" file.json','jq "\"\\(.first) \\(.last)\"" file.json'],'Conditionals':['jq "if .age >= 18 then \"adult\" else \"minor\" end" file.json','jq ".[] | select(.active)" file.json','jq ".[] | select(.name | test(\"pattern\"))" file.json','jq "try .key catch \"default\"" file.json','jq ".value // \"fallback\"" file.json']};
p=document.createElement('div');p.id='jq-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='jq JSON Processor Reference
× ';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskAgeDistribution(){
let p=document.getElementById('age-dist-panel');if(p)p.remove();
const tasks=(S.tasks||[]).filter(t=>t.status!=='done');
const now=new Date();
const buckets=[{label:'< 1 day',max:1,count:0,color:'#4ade80'},{label:'1-3 days',max:3,count:0,color:'#a3e635'},{label:'3-7 days',max:7,count:0,color:'#fbbf24'},{label:'1-2 weeks',max:14,count:0,color:'#fb923c'},{label:'2-4 weeks',max:28,count:0,color:'#f87171'},{label:'1-3 months',max:90,count:0,color:'#ef4444'},{label:'3+ months',max:Infinity,count:0,color:'#dc2626'}];
tasks.forEach(t=>{const days=(now-new Date(t.created||''))/(1000*60*60*24);for(const b of buckets){if(daysb.count),1);
p=document.createElement('div');p.id='age-dist-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:480px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
h+=''+tasks.length+' active tasks by age
';
buckets.forEach(b=>{
h+=''+b.label+' '+(b.count>0?b.count:'')+'
';
});
const avgAge=tasks.length>0?(tasks.reduce((s,t)=>s+(now-new Date(t.created||''))/(1000*60*60*24),0)/tasks.length).toFixed(1):0;
h+='Average age: '+avgAge+' days
';
p.innerHTML=h;document.body.appendChild(p);
}
function showQuickMetronome(){
let w=document.getElementById('metronome-widget');if(w)w.remove();
w=document.createElement('div');w.id='metronome-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:220px';
w.innerHTML='120
BPM
60 90 120 140
Start Stop
';
document.body.appendChild(w);
window._metInterval=null;window._metCtx=null;
window._startMetronome=function(){
window._stopMetronome();
window._metCtx=new(window.AudioContext||window.webkitAudioContext)();
const bpm=parseInt(document.getElementById('met-slider').value)||120;
const interval=60000/bpm;
window._metInterval=setInterval(()=>{
const osc=window._metCtx.createOscillator();const gain=window._metCtx.createGain();
osc.connect(gain);gain.connect(window._metCtx.destination);
osc.frequency.value=800;gain.gain.value=0.3;
osc.start();gain.gain.exponentialRampToValueAtTime(0.001,window._metCtx.currentTime+0.1);
osc.stop(window._metCtx.currentTime+0.1);
},interval);
document.getElementById('met-btn').textContent='Playing';
};
window._stopMetronome=function(){
if(window._metInterval)clearInterval(window._metInterval);window._metInterval=null;
if(window._metCtx){try{window._metCtx.close();}catch(e){}}window._metCtx=null;
const btn=document.getElementById('met-btn');if(btn)btn.textContent='Start';
};
}
function showRsyncRef(){
let p=document.getElementById('rsync-ref-panel');if(p)p.remove();
const cmds={'Basic':['rsync -av source/ dest/','rsync -av source/ user@host:dest/','rsync -av user@host:source/ dest/','rsync -avz source/ dest/ (compress)','rsync -avn source/ dest/ (dry run)','rsync -avP source/ dest/ (progress)','rsync --delete source/ dest/','rsync -av --exclude="*.tmp" source/ dest/'],'Common Flags':['-a (archive: -rlptgoD)','-v (verbose)','-z (compress during transfer)','-P (--partial --progress)','-n (dry run)','-r (recursive)','--delete (delete extraneous files)','--exclude="pattern"','--include="pattern"','--exclude-from=file','--backup --backup-dir=backup/','--max-size=100M','--min-size=1K'],'SSH & Remote':['rsync -avz -e "ssh -p 2222" source/ user@host:dest/','rsync -avz --rsh=ssh source/ user@host:dest/','rsync -avz -e "ssh -i key.pem" source/ user@host:dest/'],'Sync Patterns':['rsync -av --delete --exclude=".git" ./ dest/ (deploy)','rsync -avz ~/backup/ /Volumes/External/backup/ (local backup)','rsync -avz --progress large_file.iso user@host:/data/','rsync -av --link-dest=../prev/ source/ dest/ (incremental)'],'Useful Combos':['rsync -avzP --delete source/ dest/','rsync -av --dry-run --delete source/ dest/','rsync -av --checksum source/ dest/ (verify by checksum)','rsync -av --update source/ dest/ (skip newer on dest)','rsync -av --ignore-existing source/ dest/']};
p=document.createElement('div');p.id='rsync-ref-panel';
p.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:90vw;max-height:80vh;overflow-y:auto';
let h='';
Object.entries(cmds).forEach(([cat,list])=>{
h+=''+cat+'
';
list.forEach(c=>{h+='
'+c+'
';});
h+='
';
});
p.innerHTML=h;document.body.appendChild(p);
}
function showTaskProjectPace(){
let p=document.getElementById('pace-panel');if(p)p.remove();
const tasks=(S.tasks||[]);const projects=(S.projects||[]);
const now=new Date();const weekMs=7*24*60*60*1000;
const projPace={};
tasks.forEach(t=>{
const pid=t.project||t.projectId||'unassigned';
if(!projPace[pid])projPace[pid]={thisWeek:0,lastWeek:0,total:0,done:0};
projPace[pid].total++;
if(t.status==='done'){
projPace[pid].done++;
const completed=new Date(t.completedAt||t.created||'');
if(now-completed{
const proj=projects.find(pr=>pr.id===pid);const name=proj?proj.name:pid;
const trend=data.thisWeek>data.lastWeek?'up':data.thisWeek';
h+=''+esc(name)+' '+trendArrow+'
';
h+='';
h+='This week: '+data.thisWeek+' ';
h+='Last week: '+data.lastWeek+' ';
h+='Done: '+data.done+'/'+data.total+' ';
h+='
';
});
if(Object.keys(projPace).length===0)h+='No tasks found.
';
p.innerHTML=h;document.body.appendChild(p);
}
function showQuickSpeechSynth(){
let w=document.getElementById('speech-widget');if(w)w.remove();
w=document.createElement('div');w.id='speech-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:300px';
w.innerHTML='Speak Pause Resume Stop
';
document.body.appendChild(w);
window._speak=function(){
const text=document.getElementById('tts-input').value.trim();if(!text)return;
speechSynthesis.cancel();
const utterance=new SpeechSynthesisUtterance(text);
utterance.rate=parseFloat(document.getElementById('tts-rate').value)||1;
utterance.pitch=parseFloat(document.getElementById('tts-pitch').value)||1;
speechSynthesis.speak(utterance);
};
}
function showWgetRef(){
const cmds={
'Basic Downloads':['wget URL','wget -O file.ext URL','wget -P /dir/ URL','wget -c URL','wget -b URL','wget --limit-rate=200k URL'],
'Recursive':['wget -r URL','wget -r -l 2 URL','wget -r -np URL','wget -r -A "*.pdf" URL','wget -m URL','wget -m --convert-links URL'],
'Authentication':['wget --user=u --password=p URL','wget --header="Auth: Bearer tok" URL','wget --load-cookies cookies.txt URL','wget --save-cookies c.txt URL'],
'Multiple':['wget -i urls.txt','wget URL1 URL2 URL3','wget -i list.txt -P /dir/'],
'Options':['wget -q URL','wget -v URL','wget --spider URL','wget -t 3 URL','wget -T 10 URL','wget --no-check-certificate URL']
};
let html='';
html+='
wget Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
this.style.background=\'\',400)" style="font-family:monospace;font-size:12px;color:var(--text-primary);padding:4px 8px;cursor:pointer;border-radius:4px;margin-bottom:2px">'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskTagCloud(){
const tasks=(S.tasks||[]).filter(t=>t.status!=='done');
const tagMap={};
tasks.forEach(t=>{
if(t.project){tagMap[t.project]=(tagMap[t.project]||0)+1;}
if(t.priority){tagMap[t.priority]=(tagMap[t.priority]||0)+1;}
if(t.tags&&t.tags.length){t.tags.forEach(tg=>{tagMap[tg]=(tagMap[tg]||0)+1;});}
});
const statusCounts={};
(S.tasks||[]).forEach(t=>{statusCounts[t.status]=(statusCounts[t.status]||0)+1;});
Object.entries(statusCounts).forEach(([k,v])=>{tagMap[k]=(tagMap[k]||0)+v;});
const entries=Object.entries(tagMap).sort((a,b)=>b[1]-a[1]);
const maxCount=entries.length?entries[0][1]:1;
const colors=['#4ade80','#06b6d4','#a78bfa','#f472b6','#fbbf24','#fb923c','#ef4444','#34d399'];
let html='';
html+='
Task Tag Cloud X ';
if(!entries.length){html+='
No tags found
';}
else{
html+='
';
entries.forEach(([tag,count],i)=>{
const size=12+Math.round((count/maxCount)*20);
const color=colors[i%colors.length];
html+=''+esc(tag)+' '+count+' ';
});
html+='
';
}
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickUnitConverter(){
let w=document.getElementById('unit-conv-widget');if(w)w.remove();
w=document.createElement('div');w.id='unit-conv-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:300px';
const cats={
'Length':[['km','mi',0.621371],['m','ft',3.28084],['cm','in',0.393701],['in','cm',2.54]],
'Weight':[['kg','lb',2.20462],['lb','kg',0.453592],['oz','g',28.3495],['g','oz',0.035274]],
'Temperature':[['C','F','*'],['F','C','*']],
'Data':[['GB','MB',1024],['MB','KB',1024],['TB','GB',1024]]
};
let h='
Unit Converter X ';
h+='';
Object.keys(cats).forEach(c=>{h+=''+c+' ';});
h+=' ';
h+=' ';
h+=' ';
h+='
';
w.innerHTML=h;
document.body.appendChild(w);
window._ucCats=cats;
window._ucUpdateConv=function(){
const cat=document.getElementById('_uc-cat').value;
const sel=document.getElementById('_uc-conv');
sel.innerHTML='';
cats[cat].forEach((c,i)=>{sel.innerHTML+=''+c[0]+' to '+c[1]+' ';});
window._ucCalc();
};
window._ucCalc=function(){
const cat=document.getElementById('_uc-cat').value;
const idx=parseInt(document.getElementById('_uc-conv').value)||0;
const val=parseFloat(document.getElementById('_uc-val').value)||0;
const conv=cats[cat][idx];
let result;
if(conv[2]==='*'){
if(conv[0]==='C')result=(val*9/5)+32;
else result=(val-32)*5/9;
}else{result=val*conv[2];}
document.getElementById('_uc-result').textContent=val+' '+conv[0]+' = '+result.toFixed(4)+' '+conv[1];
};
window._ucUpdateConv();
}
function showSSHRef(){
const cmds={
'Connect':['ssh user@host','ssh -p 2222 user@host','ssh -i key.pem user@host','ssh -v user@host','ssh -J jumphost user@dest'],
'Keys':['ssh-keygen -t ed25519 -C "email"','ssh-copy-id user@host','ssh-add ~/.ssh/id_ed25519','ssh-agent bash','ssh-keygen -R hostname'],
'Tunnels':['ssh -L 8080:localhost:80 user@host','ssh -R 9090:localhost:3000 user@host','ssh -D 1080 user@host','ssh -fN -L 5432:db:5432 user@host'],
'SCP':['scp file user@host:/path','scp user@host:/file ./local','scp -r dir/ user@host:/path','scp -P 2222 file user@host:/path'],
'Config':['~/.ssh/config','Host alias',' HostName x.x.x.x',' User deploy',' IdentityFile ~/.ssh/key',' Port 22']
};
let html='';
html+='
SSH Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
this.style.background=\'\',400)" style="font-family:monospace;font-size:12px;color:var(--text-primary);padding:4px 8px;cursor:pointer;border-radius:4px;margin-bottom:2px">'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskCompletionRate(){
const tasks=S.tasks||[];
const now=new Date();
const weeks=[];
for(let i=7;i>=0;i--){
const start=new Date(now);start.setDate(start.getDate()-i*7);
const end=new Date(start);end.setDate(end.getDate()+7);
const created=tasks.filter(t=>{const d=new Date(t.createdAt||0);return d>=start&&d{if(t.status!=='done')return false;const d=new Date(t.completedAt||t.updatedAt||0);return d>=start&&dCompletion Rate Over Time X ';
const maxVal=Math.max(...weeks.map(w=>Math.max(w.created,w.done)),1);
html+='';
const bw=500/8;
weeks.forEach((w,i)=>{
const x=i*bw+10;
const ch=w.created?(w.created/maxVal)*150:0;
const dh=w.done?(w.done/maxVal)*150:0;
html+=' ';
html+=' ';
html+=''+w.label+' ';
});
html+=' ';
html+=' Created Done
';
html+='Week Created Done Rate ';
weeks.forEach(w=>{
html+=''+w.label+' '+w.created+' '+w.done+' '+w.rate+'% ';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickTimer(){
let w=document.getElementById('quick-timer-widget');if(w)w.remove();
w=document.createElement('div');w.id='quick-timer-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:260px';
let h='
Quick Timer X ';
h+='';
[1,2,5,10,15,25,30,45,60].forEach(m=>{
h+=''+m+'m ';
});
h+='
';
h+='00:00
';
h+='';
h+='Pause ';
h+='Reset ';
h+='
';
w.innerHTML=h;
document.body.appendChild(w);
window._qtRemaining=0;
window._qtPaused=false;
window._qtStart=function(mins){
if(window._qtInterval)clearInterval(window._qtInterval);
window._qtRemaining=mins*60;
window._qtPaused=false;
document.getElementById('_qt-pause').style.display='inline-block';
document.getElementById('_qt-pause').textContent='Pause';
window._qtTick();
window._qtInterval=setInterval(window._qtTick,1000);
};
window._qtTick=function(){
if(window._qtPaused)return;
const m=Math.floor(window._qtRemaining/60);
const s=window._qtRemaining%60;
const el=document.getElementById('_qt-display');
if(el)el.textContent=String(m).padStart(2,'0')+':'+String(s).padStart(2,'0');
if(window._qtRemaining<=0){
clearInterval(window._qtInterval);
if(el)el.style.color='#ef4444';
try{new Audio('data:audio/wav;base64,UklGRnoGAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQoGAACBhYqFbF1dZHB5g4eGg3x3eX5/g4WFhIKBgYKEhYaGhoWEhIWGh4eHh4aFhYWGh4eHh4aFhYaGh4eHhoaFhYaGh4eHhoaFhQ==').play();}catch(e){}
return;
}
window._qtRemaining--;
};
window._qtPause=function(){
window._qtPaused=!window._qtPaused;
document.getElementById('_qt-pause').textContent=window._qtPaused?'Resume':'Pause';
};
}
function showNginxRef(){
const cmds={
'Server Block':['server { listen 80; server_name example.com; root /var/www/html; }','location / { try_files $uri $uri/ =404; }','location ~ \\.php$ { fastcgi_pass 127.0.0.1:9000; }'],
'Proxy':['proxy_pass http://localhost:3000;','proxy_set_header Host $host;','proxy_set_header X-Real-IP $remote_addr;','proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;'],
'SSL':['listen 443 ssl;','ssl_certificate /path/cert.pem;','ssl_certificate_key /path/key.pem;','ssl_protocols TLSv1.2 TLSv1.3;'],
'Redirect':['return 301 https://$host$request_uri;','rewrite ^/old(.*)$ /new$1 permanent;','return 302 /maintenance;'],
'Commands':['nginx -t','nginx -s reload','nginx -s stop','nginx -V','systemctl restart nginx'],
'Caching':['proxy_cache_path /tmp/cache levels=1:2 keys_zone=my_cache:10m;','proxy_cache my_cache;','expires 30d;','add_header Cache-Control "public, immutable";']
};
let html='';
html+='
nginx Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
this.style.background=\'\',400)" style="font-family:monospace;font-size:12px;color:var(--text-primary);padding:4px 8px;cursor:pointer;border-radius:4px;margin-bottom:2px">'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskCycleTime(){
const tasks=(S.tasks||[]).filter(t=>t.status==='done'&&t.createdAt&&(t.completedAt||t.updatedAt));
let html='';
html+='
Cycle Time Analysis X ';
if(!tasks.length){html+='
No completed tasks with timestamps
';document.body.insertAdjacentHTML('beforeend',html);return;}
const cycles=tasks.map(t=>{
const created=new Date(t.createdAt);
const done=new Date(t.completedAt||t.updatedAt);
const days=Math.max(0,Math.round((done-created)/(1000*60*60*24)));
return {title:t.title,days,priority:t.priority||'p3'};
}).sort((a,b)=>a.days-b.days);
const avg=Math.round(cycles.reduce((s,c)=>s+c.days,0)/cycles.length);
const median=cycles[Math.floor(cycles.length/2)].days;
const maxD=Math.max(...cycles.map(c=>c.days),1);
html+='';
html+='
';
html+='
';
html+='
';
html+='
';
const buckets={'0-1d':0,'2-3d':0,'4-7d':0,'1-2w':0,'2w+':0};
cycles.forEach(c=>{if(c.days<=1)buckets['0-1d']++;else if(c.days<=3)buckets['2-3d']++;else if(c.days<=7)buckets['4-7d']++;else if(c.days<=14)buckets['1-2w']++;else buckets['2w+']++;});
const maxB=Math.max(...Object.values(buckets),1);
html+='';
Object.entries(buckets).forEach(([k,v])=>{
const pct=Math.round(v/maxB*100);
html+='
';
});
html+='
';
html+='Sorted fastest to slowest (top 10):
';
cycles.slice(0,10).forEach(c=>{
const pColor=c.priority==='p0'?'#ef4444':c.priority==='p1'?'#f97316':c.priority==='p2'?'#3b82f6':'#6b7280';
html+=''+esc(c.title)+' '+c.priority+' '+c.days+'d
';
});
html+='';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickColorConverter(){
let w=document.getElementById('color-conv-widget');if(w)w.remove();
w=document.createElement('div');w.id='color-conv-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:300px';
let h='
Color Converter X ';
h+='
';
h+=' ';
h+='
';
h+='
';
h+='Copy HEX ';
w.innerHTML=h;
document.body.appendChild(w);
window._ccFromHex=function(){
const hex=document.getElementById('_cc-hex').value.replace('#','');
if(hex.length!==6)return;
const r=parseInt(hex.substring(0,2),16),g=parseInt(hex.substring(2,4),16),b=parseInt(hex.substring(4,6),16);
document.getElementById('_cc-r').value=r;document.getElementById('_cc-g').value=g;document.getElementById('_cc-b').value=b;
document.getElementById('_cc-preview').style.background='#'+hex;
const rf=r/255,gf=g/255,bf=b/255;const max=Math.max(rf,gf,bf),min=Math.min(rf,gf,bf);
let hue=0,sat=0,light=(max+min)/2;
if(max!==min){const d=max-min;sat=light>0.5?d/(2-max-min):d/(max+min);if(max===rf)hue=((gf-bf)/d+(gfv.toString(16).padStart(2,'0')).join('');
document.getElementById('_cc-hex').value=hex;document.getElementById('_cc-preview').style.background=hex;
const rf=r/255,gf=g/255,bf=b/255;const max=Math.max(rf,gf,bf),min=Math.min(rf,gf,bf);
let hue=0,sat=0,light=(max+min)/2;
if(max!==min){const d=max-min;sat=light>0.5?d/(2-max-min):d/(max+min);if(max===rf)hue=((gf-bf)/d+(gf{if(t<0)t+=1;if(t>1)t-=1;if(t<1/6)return p+(q-p)*6*t;if(t<1/2)return q;if(t<2/3)return p+(q-p)*(2/3-t)*6;return p;};
const q=l<0.5?l*(1+s):l+s-l*s;const p=2*l-q;
r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3);
}
r=Math.round(r*255);g=Math.round(g*255);b=Math.round(b*255);
document.getElementById('_cc-r').value=r;document.getElementById('_cc-g').value=g;document.getElementById('_cc-b').value=b;
const hex='#'+[r,g,b].map(v=>v.toString(16).padStart(2,'0')).join('');
document.getElementById('_cc-hex').value=hex;document.getElementById('_cc-preview').style.background=hex;
};
}
function showApacheRef(){
const cmds={
'VirtualHost':['',' ServerName example.com',' DocumentRoot /var/www/html',' ErrorLog ${APACHE_LOG_DIR}/error.log',' '],
'Modules':['a2enmod rewrite','a2enmod ssl','a2enmod proxy','a2enmod headers','a2dismod status'],
'Rewrite':['RewriteEngine On','RewriteCond %{HTTPS} off','RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]','RewriteRule ^old /new [R=301]'],
'Commands':['apachectl start','apachectl stop','apachectl restart','apachectl graceful','apachectl configtest','apache2ctl -S'],
'Security':['Header set X-Frame-Options SAMEORIGIN','Header set X-Content-Type-Options nosniff','Header set X-XSS-Protection "1; mode=block"','ServerTokens Prod','ServerSignature Off']
};
let html='';
html+='
Apache/httpd Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
this.style.background=\'\',400)" style="font-family:monospace;font-size:12px;color:var(--text-primary);padding:4px 8px;cursor:pointer;border-radius:4px;margin-bottom:2px">'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskWorkloadBalance(){
const tasks=(S.tasks||[]).filter(t=>t.status!=='done');
const projects={};
tasks.forEach(t=>{
const p=t.project||'No Project';
if(!projects[p])projects[p]={total:0,p0:0,p1:0,p2:0,p3:0};
projects[p].total++;
projects[p][t.priority||'p3']++;
});
const entries=Object.entries(projects).sort((a,b)=>b[1].total-a[1].total);
const maxT=entries.length?Math.max(...entries.map(e=>e[1].total)):1;
let html='';
html+='
Workload Balance X ';
if(!entries.length){html+='
No active tasks
';document.body.insertAdjacentHTML('beforeend',html);return;}
const totalAll=entries.reduce((s,e)=>s+e[1].total,0);
entries.forEach(([proj,data])=>{
const pct=Math.round(data.total/totalAll*100);
const barW=Math.round(data.total/maxT*100);
html+=''+esc(proj)+' '+data.total+' tasks ('+pct+'%)
';
html+='
';
const p0w=data.total?Math.round(data.p0/data.total*barW):0;
const p1w=data.total?Math.round(data.p1/data.total*barW):0;
const p2w=data.total?Math.round(data.p2/data.total*barW):0;
const p3w=barW-p0w-p1w-p2w;
if(p0w)html+='
';
if(p1w)html+='
';
if(p2w)html+='
';
if(p3w)html+='
';
html+='
';
});
html+=' P0 P1 P2 P3
';
html+='';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickCharCounter(){
let w=document.getElementById('char-counter-widget');if(w)w.remove();
w=document.createElement('div');w.id='char-counter-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:320px';
let h='
Character Counter X ';
h+='';
h+='Limit: ';
[280,500,1000,2000,5000].forEach(lim=>{
h+=''+lim+' ';
});
h+='
';
h+='
';
h+='';
w.innerHTML=h;
document.body.appendChild(w);
window._chcLimit=280;
window._chcUpdate=function(){
const text=document.getElementById('_chc-input').value;
const chars=text.length;
const words=text.trim()?text.trim().split(/\s+/).length:0;
const sentences=text.trim()?text.split(/[.!?]+/).filter(s=>s.trim()).length:0;
const paragraphs=text.trim()?text.split(/\n\n+/).filter(s=>s.trim()).length:0;
const lines=text?text.split('\n').length:0;
const pct=window._chcLimit?Math.min(100,Math.round(chars/window._chcLimit*100)):0;
const stats=document.getElementById('_chc-stats');
stats.innerHTML=''+chars+' chars
'+words+' words
'+sentences+' sentences
'+paragraphs+' paragraphs
'+lines+' lines
'+pct+'% of '+window._chcLimit+'
';
const bar=document.getElementById('_chc-bar-fill');
bar.style.width=Math.min(100,pct)+'%';
bar.style.background=pct>100?'#ef4444':pct>80?'#fbbf24':'#4ade80';
};
}
function showElasticsearchRef(){
const cmds={
'Index':['PUT /my-index','DELETE /my-index','GET /my-index/_mapping','GET /_cat/indices?v','POST /my-index/_refresh'],
'Document':['POST /idx/_doc {"field":"val"}','GET /idx/_doc/id','PUT /idx/_doc/id {"field":"val"}','DELETE /idx/_doc/id','POST /idx/_bulk'],
'Search':['GET /idx/_search {"query":{"match_all":{}}}','GET /idx/_search {"query":{"match":{"field":"val"}}}','GET /idx/_search {"query":{"bool":{"must":[...],"filter":[...]}}}','GET /idx/_search {"query":{"range":{"date":{"gte":"now-1d"}}}}'],
'Aggregation':['{"aggs":{"name":{"terms":{"field":"status"}}}}','{"aggs":{"avg_price":{"avg":{"field":"price"}}}}','{"aggs":{"by_date":{"date_histogram":{"field":"ts","interval":"1d"}}}}'],
'Cluster':['GET /_cluster/health','GET /_cat/nodes?v','GET /_cat/shards?v','GET /_cluster/stats']
};
let html='';
html+='
Elasticsearch Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskPriorityMatrix(){
const tasks=(S.tasks||[]).filter(t=>t.status!=='done');
const urgent=[],important=[],delegate=[],eliminate=[];
tasks.forEach(t=>{
const isUrgent=t.priority==='p0'||t.priority==='p1';
const isImportant=t.priority==='p0'||t.priority==='p2';
if(isUrgent&&isImportant)urgent.push(t);
else if(!isUrgent&&isImportant)important.push(t);
else if(isUrgent&&!isImportant)delegate.push(t);
else eliminate.push(t);
});
let html='';
html+='
Eisenhower Priority Matrix X ';
html+='
';
const quadrants=[
{title:'DO FIRST',subtitle:'Urgent + Important',items:urgent,bg:'#ef444422',color:'#ef4444'},
{title:'SCHEDULE',subtitle:'Important, Not Urgent',items:important,bg:'#3b82f622',color:'#3b82f6'},
{title:'DELEGATE',subtitle:'Urgent, Not Important',items:delegate,bg:'#f9731622',color:'#f97316'},
{title:'ELIMINATE',subtitle:'Neither',items:eliminate,bg:'#6b728022',color:'#6b7280'}
];
quadrants.forEach(q=>{
html+='
';
html+='
'+q.title+' ('+q.items.length+')
';
html+='
'+q.subtitle+'
';
q.items.slice(0,5).forEach(t=>{
html+='
'+esc(t.title)+'
';
});
if(q.items.length>5)html+='
+'+(q.items.length-5)+' more
';
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickBase64(){
let w=document.getElementById('base64-widget');if(w)w.remove();
w=document.createElement('div');w.id='base64-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:340px';
let h='
Base64 Encode/Decode X ';
h+='';
h+='';
h+='Encode ';
h+='Decode ';
h+='
';
h+='';
h+='Copy Result ';
w.innerHTML=h;
document.body.appendChild(w);
}
function showRedisRef(){
const cmds={
'Strings':['SET key value','GET key','MSET k1 v1 k2 v2','MGET k1 k2','INCR key','DECR key','APPEND key value','SETEX key 3600 value'],
'Hash':['HSET key field value','HGET key field','HGETALL key','HDEL key field','HINCRBY key field 1'],
'List':['LPUSH key value','RPUSH key value','LPOP key','RPOP key','LRANGE key 0 -1','LLEN key'],
'Set':['SADD key member','SREM key member','SMEMBERS key','SINTER k1 k2','SUNION k1 k2','SCARD key'],
'Sorted Set':['ZADD key score member','ZRANGE key 0 -1 WITHSCORES','ZRANGEBYSCORE key min max','ZREM key member','ZCARD key'],
'Keys':['KEYS pattern','EXISTS key','DEL key','EXPIRE key 3600','TTL key','TYPE key','SCAN 0 MATCH pattern COUNT 100'],
'Server':['INFO','DBSIZE','FLUSHDB','FLUSHALL','CONFIG GET maxmemory','MONITOR','SLOWLOG GET 10']
};
let html='';
html+='
Redis Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
this.style.background=\'\',400)" style="font-family:monospace;font-size:12px;color:var(--text-primary);padding:4px 8px;cursor:pointer;border-radius:4px;margin-bottom:2px">'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskStreakTracker(){
const tasks=S.tasks||[];
const now=new Date();
const days=[];
for(let i=29;i>=0;i--){
const d=new Date(now);d.setDate(d.getDate()-i);
const ds=d.toISOString().split('T')[0];
const done=tasks.filter(t=>t.status==='done'&&(t.completedAt||t.updatedAt||'').startsWith(ds)).length;
days.push({date:ds,done,day:d.getDay()});
}
let currentStreak=0;
for(let i=days.length-1;i>=0;i--){
if(days[i].done>0)currentStreak++;else break;
}
let bestStreak=0,tempStreak=0;
days.forEach(d=>{if(d.done>0){tempStreak++;if(tempStreak>bestStreak)bestStreak=tempStreak;}else tempStreak=0;});
const totalDone=days.reduce((s,d)=>s+d.done,0);
let html='';
html+='
Daily Streak Tracker X ';
html+='
';
html+='
'+currentStreak+'
Current Streak
';
html+='
'+bestStreak+'
Best Streak
';
html+='
'+totalDone+'
30-Day Total
';
html+='
';
html+='
';
const maxDone=Math.max(...days.map(d=>d.done),1);
days.forEach(d=>{
const opacity=d.done>0?0.3+0.7*(d.done/maxDone):0.1;
const bg=d.done>0?'rgba(74,222,128,'+opacity+')':'var(--bg-surface)';
const label=d.date.split('-').slice(1).join('/')+' '+d.done+' done';
html+='
'+((d.done>0)?d.done:'')+'
';
});
html+='
';
html+='
Last 30 days - complete at least 1 task daily to maintain streak
';
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickJsonFormatter(){
let w=document.getElementById('json-fmt-widget');if(w)w.remove();
w=document.createElement('div');w.id='json-fmt-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:360px';
let h='
JSON Formatter X ';
h+='';
h+='';
h+='Prettify ';
h+='Minify ';
h+='
';
h+='
';
h+='Copy ';
w.innerHTML=h;
document.body.appendChild(w);
}
function showMongoDBRef(){
const cmds={
'CRUD':['db.col.insertOne({k:"v"})','db.col.insertMany([{a:1},{a:2}])','db.col.find({status:"active"})','db.col.findOne({_id:ObjectId("...")})','db.col.updateOne({_id:id},{$set:{k:"v"}})','db.col.updateMany({},{$inc:{count:1}})','db.col.deleteOne({_id:id})','db.col.deleteMany({status:"old"})'],
'Query':['db.col.find({age:{$gt:25}})','db.col.find({tags:{$in:["a","b"]}})','db.col.find({$or:[{a:1},{b:2}]})','db.col.find().sort({date:-1}).limit(10)','db.col.find({},{name:1,_id:0})','db.col.countDocuments({status:"active"})'],
'Aggregate':['db.col.aggregate([{$match:{}},{$group:{_id:"$field",total:{$sum:1}}}])','$lookup: {from:"other",localField:"id",foreignField:"ref",as:"joined"}','$project, $unwind, $sort, $limit, $skip'],
'Index':['db.col.createIndex({field:1})','db.col.createIndex({a:1,b:-1})','db.col.createIndex({field:"text"})','db.col.getIndexes()','db.col.dropIndex("name")'],
'Admin':['show dbs','use mydb','show collections','db.stats()','db.col.stats()','db.dropDatabase()']
};
let html='';
html+='
MongoDB Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskFocusScore(){
const tasks=S.tasks||[];
const now=new Date();
const today=now.toISOString().split('T')[0];
const thisWeekStart=new Date(now);thisWeekStart.setDate(thisWeekStart.getDate()-thisWeekStart.getDay());
const todayDone=tasks.filter(t=>t.status==='done'&&(t.completedAt||t.updatedAt||'').startsWith(today)).length;
const weekDone=tasks.filter(t=>{if(t.status!=='done')return false;const d=new Date(t.completedAt||t.updatedAt||0);return d>=thisWeekStart;}).length;
const activeCount=tasks.filter(t=>t.status==='in-progress').length;
const overdue=tasks.filter(t=>t.status!=='done'&&t.due&&new Date(t.due)t.status==='done'&&t.priority==='p0').length;
const p0Total=tasks.filter(t=>t.priority==='p0').length;
let score=50;
score+=Math.min(todayDone*5,20);
score+=Math.min(weekDone*2,15);
score-=overdue*3;
score-=Math.max(activeCount-3,0)*2;
if(p0Total>0)score+=Math.round(p0Done/p0Total*15);
score=Math.max(0,Math.min(100,score));
const grade=score>=90?'A+':score>=80?'A':score>=70?'B':score>=60?'C':score>=50?'D':'F';
const gradeColor=score>=80?'#4ade80':score>=60?'#fbbf24':'#ef4444';
let html='';
html+='
Focus Score X ';
html+='
';
html+='
';
html+='
Today done: '+todayDone+'
';
html+='
Week done: '+weekDone+'
';
html+='
In progress: '+activeCount+'
';
html+='
Overdue: '+overdue+'
';
html+='
P0 done: '+p0Done+'/'+p0Total+'
';
html+='
';
html+='
Score based on completions, overdue count, WIP, and P0 ratio
';
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickUrlEncoder(){
let w=document.getElementById('url-enc-widget');if(w)w.remove();
w=document.createElement('div');w.id='url-enc-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:320px';
let h='
URL Encode/Decode X ';
h+='';
h+='';
h+='Encode ';
h+='Decode ';
h+='encodeURI ';
h+='
';
h+='';
h+='Copy ';
w.innerHTML=h;
document.body.appendChild(w);
}
function showGrafanaRef(){
const cmds={
'PromQL Basics':['metric_name','metric_name{label="value"}','rate(metric[5m])','increase(metric[1h])','sum(rate(http_requests_total[5m]))','avg by(instance)(cpu_usage)'],
'PromQL Functions':['histogram_quantile(0.99, rate(http_duration_bucket[5m]))','topk(10, http_requests_total)','bottomk(5, node_memory_free)','count(up == 1)','absent(metric)','changes(metric[5m])'],
'PromQL Aggregation':['sum by(label)(metric)','avg without(instance)(metric)','max(metric) by(job)','min(metric)','count(metric)','stddev(metric)'],
'Grafana Variables':['$__interval','$__rate_interval','$__timeFrom()','$__timeTo()','$__range','${var:csv}','${var:pipe}'],
'Alert Rules':['WHEN avg() OF query IS ABOVE threshold','FOR 5m','Labels: severity=critical','Annotations: summary, description']
};
let html='';
html+='
Grafana / PromQL Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskProjectHealth(){
const projects=S.projects||[];
const tasks=S.tasks||[];
const content=S.content||[];
const docs=S.writerDocs||[];
let html='';
html+='
Project Health Dashboard X ';
if(!projects.length){html+='
No projects
';document.body.insertAdjacentHTML('beforeend',html);return;}
projects.forEach(p=>{
const pTasks=tasks.filter(t=>t.project===p.name||t.projectId===p.id);
const done=pTasks.filter(t=>t.status==='done').length;
const active=pTasks.filter(t=>t.status==='in-progress').length;
const overdue=pTasks.filter(t=>t.status!=='done'&&t.due&&new Date(t.due)c.project===p.name).length;
const pDocs=docs.filter(d=>d.project===p.name).length;
const healthScore=Math.min(100,pct+(overdue>0?-15:10)+(active>0?5:0));
const healthColor=healthScore>=70?'#4ade80':healthScore>=40?'#fbbf24':'#ef4444';
html+='';
html+='
'+esc(p.name)+' '+healthScore+'
';
html+='
';
html+='
';
html+='Tasks: '+done+'/'+total+' ';
html+='Active: '+active+' ';
if(overdue)html+='Overdue: '+overdue+' ';
html+='Content: '+pContent+' ';
html+='Docs: '+pDocs+' ';
html+='
';
});
html+='';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickHashGenerator(){
let w=document.getElementById('hash-gen-widget');if(w)w.remove();
w=document.createElement('div');w.id='hash-gen-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:340px';
let h='
Hash Generator X ';
h+='';
h+='';
['SHA-256','SHA-384','SHA-512','SHA-1'].forEach(alg=>{
h+=''+alg.replace('SHA-','')+' ';
});
h+='
';
h+='
';
h+='Copy Hash ';
w.innerHTML=h;
document.body.appendChild(w);
window._hgCalc=async function(alg){
const text=document.getElementById('_hg-input').value;
if(!text){document.getElementById('_hg-result').textContent='Enter text first';return;}
const buf=await crypto.subtle.digest(alg,new TextEncoder().encode(text));
const hex=Array.from(new Uint8Array(buf)).map(b=>b.toString(16).padStart(2,'0')).join('');
document.getElementById('_hg-result').textContent=alg+': '+hex;
};
}
function showPostgresRef(){
const cmds={
'Database':['CREATE DATABASE mydb;','DROP DATABASE mydb;','\\l','\\c mydb','\\dt','\\d tablename'],
'Table':['CREATE TABLE t (id SERIAL PRIMARY KEY, name VARCHAR(100), created_at TIMESTAMP DEFAULT NOW());','ALTER TABLE t ADD COLUMN email VARCHAR(255);','ALTER TABLE t DROP COLUMN email;','DROP TABLE t;','TRUNCATE TABLE t;'],
'CRUD':['INSERT INTO t (name) VALUES (\'val\');','SELECT * FROM t WHERE id = 1;','UPDATE t SET name = \'new\' WHERE id = 1;','DELETE FROM t WHERE id = 1;','SELECT * FROM t ORDER BY created_at DESC LIMIT 10;'],
'Query':['SELECT DISTINCT col FROM t;','SELECT COUNT(*), status FROM t GROUP BY status HAVING COUNT(*) > 5;','SELECT * FROM t1 JOIN t2 ON t1.id = t2.ref_id;','SELECT * FROM t WHERE name ILIKE \'%search%\';','SELECT * FROM t WHERE created_at > NOW() - INTERVAL \'7 days\';'],
'Index':['CREATE INDEX idx_name ON t (col);','CREATE UNIQUE INDEX idx ON t (col);','DROP INDEX idx_name;','REINDEX TABLE t;'],
'Admin':['pg_dump mydb > backup.sql','psql mydb < backup.sql','VACUUM ANALYZE;','EXPLAIN ANALYZE SELECT ...;','SELECT pg_size_pretty(pg_database_size(\'mydb\'));']
};
let html='';
html+='
PostgreSQL Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskMilestoneTracker(){
if(!S._milestones)S._milestones=[];
let html='';
html+='
Milestone Tracker X ';
html+='
Add
';
html+='
';
const now=new Date();
S._milestones.sort((a,b)=>new Date(a.deadline)-new Date(b.deadline)).forEach((m,i)=>{
const deadline=new Date(m.deadline);
const daysLeft=Math.ceil((deadline-now)/(1000*60*60*24));
const statusColor=m.done?'#4ade80':daysLeft<0?'#ef4444':daysLeft<=7?'#fbbf24':'var(--text-muted)';
const statusText=m.done?'Done':daysLeft<0?Math.abs(daysLeft)+'d overdue':daysLeft===0?'Today':daysLeft+'d left';
html+='
';
html+='
';
html+='
'+esc(m.title)+'
'+m.deadline+'
';
html+='
'+statusText+' ';
html+='
x ';
html+='
';
});
if(!S._milestones.length)html+='
No milestones set. Add your first milestone above.
';
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
window._msAdd=function(){
const title=document.getElementById('_ms-title').value.trim();
const deadline=document.getElementById('_ms-date').value;
if(!title||!deadline)return;
S._milestones.push({title,deadline,done:false,createdAt:new Date().toISOString()});
save();
document.querySelector('div[style*=fixed]').remove();
showTaskMilestoneTracker();
};
}
function showQuickTimezoneConverter(){
let w=document.getElementById('tz-conv-widget');if(w)w.remove();
w=document.createElement('div');w.id='tz-conv-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:320px';
const zones=['America/New_York','America/Chicago','America/Denver','America/Los_Angeles','Europe/London','Europe/Paris','Europe/Berlin','Asia/Tokyo','Asia/Shanghai','Asia/Kolkata','Australia/Sydney','Pacific/Auckland'];
let h='
Timezone Converter X ';
h+='';
const now=new Date();
zones.forEach(tz=>{
try{
const time=now.toLocaleString('en-US',{timeZone:tz,hour:'2-digit',minute:'2-digit',hour12:true});
const date=now.toLocaleString('en-US',{timeZone:tz,weekday:'short',month:'short',day:'numeric'});
const label=tz.split('/').pop().replace(/_/g,' ');
h+='
';
}catch(e){}
});
h+='
';
h+='Refresh ';
w.innerHTML=h;
document.body.appendChild(w);
}
function showVercelCLIRef(){
const cmds={
'Deploy':['vercel','vercel --prod','vercel deploy','vercel deploy --prebuilt','vercel build','vercel dev'],
'Project':['vercel project ls','vercel project add','vercel project rm name','vercel link','vercel pull'],
'Env':['vercel env ls','vercel env add VAR_NAME','vercel env rm VAR_NAME','vercel env pull .env.local'],
'Domains':['vercel domains ls','vercel domains add example.com','vercel domains rm example.com','vercel dns ls example.com','vercel certs ls'],
'Logs':['vercel logs url','vercel logs url --follow','vercel inspect url'],
'Other':['vercel whoami','vercel login','vercel logout','vercel switch','vercel --version']
};
let html='';
html+='
Vercel CLI Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
this.style.background=\'\',400)" style="font-family:monospace;font-size:12px;color:var(--text-primary);padding:4px 8px;cursor:pointer;border-radius:4px;margin-bottom:2px">'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskEffortEstimator(){
const tasks=(S.tasks||[]).filter(t=>t.status!=='done');
const sizes={XS:1,S:2,M:5,L:8,XL:13};
let html='';
html+='
Effort Estimator X ';
html+='
';
Object.entries(sizes).forEach(([size,pts])=>{
html+='
';
});
html+='
';
if(!tasks.length){html+='
No active tasks to estimate
';document.body.insertAdjacentHTML('beforeend',html);return;}
let totalPts=0;
tasks.slice(0,15).forEach((t,i)=>{
const est=t.estimate||'';
const size=Object.keys(sizes).find(s=>est.toUpperCase().includes(s))||'';
const pts=size?sizes[size]:0;
totalPts+=pts;
html+='';
html+='
'+esc(t.title)+'
';
html+='
';
Object.keys(sizes).forEach(s=>{
const active=size===s;
html+=''+s+' ';
});
html+='
';
});
html+='Total: '+totalPts+' points
';
if(tasks.length>15)html+='Showing 15 of '+tasks.length+' tasks
';
html+='';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickClipboardHistory(){
if(!S._clipHistory)S._clipHistory=[];
let w=document.getElementById('clip-hist-widget');if(w)w.remove();
w=document.createElement('div');w.id='clip-hist-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:320px';
let h='
Clipboard History X ';
h+='Capture Current Clear
';
h+='';
if(!S._clipHistory.length){h+='
No clipboard history. Click "Capture Current" to save clipboard.
';}
S._clipHistory.forEach((item,i)=>{
const preview=item.length>60?item.substring(0,60)+'...':item;
h+='
'+esc(preview)+'
';
});
h+='
';
w.innerHTML=h;
document.body.appendChild(w);
}
function showMySQLRef(){
const cmds={
'Database':['CREATE DATABASE mydb;','DROP DATABASE mydb;','SHOW DATABASES;','USE mydb;','SHOW TABLES;','DESCRIBE tablename;'],
'Table':['CREATE TABLE t (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), created DATETIME DEFAULT NOW());','ALTER TABLE t ADD email VARCHAR(255);','ALTER TABLE t MODIFY col VARCHAR(200);','DROP TABLE t;','RENAME TABLE old TO new;'],
'CRUD':['INSERT INTO t (name) VALUES ("val");','SELECT * FROM t WHERE id = 1;','UPDATE t SET name = "new" WHERE id = 1;','DELETE FROM t WHERE id = 1;','REPLACE INTO t (id, name) VALUES (1, "val");'],
'Query':['SELECT * FROM t ORDER BY id DESC LIMIT 10 OFFSET 20;','SELECT COUNT(*), status FROM t GROUP BY status;','SELECT * FROM t1 INNER JOIN t2 ON t1.id = t2.ref;','SELECT * FROM t WHERE name LIKE "%search%";','SELECT * FROM t WHERE created > DATE_SUB(NOW(), INTERVAL 7 DAY);'],
'Admin':['mysqldump mydb > backup.sql','mysql mydb < backup.sql','SHOW PROCESSLIST;','EXPLAIN SELECT ...;','SHOW ENGINE INNODB STATUS;','SET GLOBAL max_connections = 200;']
};
let html='';
html+='
MySQL Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskDailyPlanner(){
if(!S._dailyBlocks)S._dailyBlocks={};
const today=new Date().toISOString().split('T')[0];
if(!S._dailyBlocks[today])S._dailyBlocks[today]={};
const hours=['06:00','07:00','08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00','20:00','21:00'];
let html='';
html+='
Daily Planner - '+today+' X ';
hours.forEach(hr=>{
const val=S._dailyBlocks[today][hr]||'';
html+='
';
html+=''+hr+' ';
html+=' ';
html+='
';
});
html+='
Export ';
html+='Clear
';
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickMarkdownToHTML(){
let w=document.getElementById('md-html-widget');if(w)w.remove();
w=document.createElement('div');w.id='md-html-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:360px';
let h='
Markdown to HTML X ';
h+='';
h+='Convert ';
h+='';
h+='Copy HTML ';
w.innerHTML=h;
document.body.appendChild(w);
window._mdConvert=function(){
let md=document.getElementById('_md-input').value;
let html=md;
html=html.replace(/^### (.+)$/gm,'$1 ');
html=html.replace(/^## (.+)$/gm,'$1 ');
html=html.replace(/^# (.+)$/gm,'$1 ');
html=html.replace(/\*\*(.+?)\*\*/g,'$1 ');
html=html.replace(/\*(.+?)\*/g,'$1 ');
html=html.replace(/`(.+?)`/g,'$1');
html=html.replace(/^\- (.+)$/gm,'$1 ');
html=html.replace(/^\d+\. (.+)$/gm,'$1 ');
html=html.replace(/\[(.+?)\]\((.+?)\)/g,'$1 ');
html=html.replace(/^---$/gm,' ');
html=html.replace(/\n\n/g,'');
document.getElementById('_md-output').value=html;
};
}
function showGitHubActionsRef(){
const cmds={
'Workflow':['name: CI','on: [push, pull_request]','on: push: branches: [main]','on: schedule: - cron: "0 0 * * *"','on: workflow_dispatch:'],
'Jobs':['jobs: build: runs-on: ubuntu-latest','needs: [test]','if: github.event_name == \'push\'','strategy: matrix: node: [16, 18, 20]','timeout-minutes: 30'],
'Steps':['- uses: actions/checkout@v4','- uses: actions/setup-node@v4 with: node-version: 20','- run: npm ci','- run: npm test','- run: npm run build'],
'Secrets':['${{ secrets.GITHUB_TOKEN }}','${{ secrets.MY_SECRET }}','${{ github.sha }}','${{ github.ref }}','${{ github.actor }}'],
'Cache':['- uses: actions/cache@v4 with: path: node_modules key: ${{ runner.os }}-node-${{ hashFiles(\'package-lock.json\') }}'],
'Deploy':['- uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./dist','- uses: amondnet/vercel-action@v20']
};
let html='
';
html+='
GitHub Actions Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskWeeklyPlanner(){
if(!S._weeklyPlan)S._weeklyPlan={};
const now=new Date();
const weekStart=new Date(now);weekStart.setDate(weekStart.getDate()-weekStart.getDay());
const weekKey=weekStart.toISOString().split('T')[0];
if(!S._weeklyPlan[weekKey])S._weeklyPlan[weekKey]={};
const days=['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
let html='';
html+='
Weekly Planner X ';
html+='
';
days.forEach((day,i)=>{
const d=new Date(weekStart);d.setDate(d.getDate()+i);
const dateStr=d.toISOString().split('T')[0];
const isToday=dateStr===now.toISOString().split('T')[0];
const val=S._weeklyPlan[weekKey][day]||'';
html+='
';
html+='
'+day+'
';
html+='
'+(d.getMonth()+1)+'/'+d.getDate()+'
';
html+='
';
html+='
';
});
html+='
';
html+='
Export Week ';
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickRegexTester(){
let w=document.getElementById('regex-test-widget');if(w)w.remove();
w=document.createElement('div');w.id='regex-test-widget';
w.style.cssText='position:fixed;bottom:20px;left:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:360px';
let h='
Regex Tester X ';
h+=' ';
h+=' g i m
';
h+='';
h+='
';
w.innerHTML=h;
document.body.appendChild(w);
window._rxTest=function(){
const pattern=document.getElementById('_rx-pattern').value;
const input=document.getElementById('_rx-input').value;
const result=document.getElementById('_rx-result');
if(!pattern){result.innerHTML='Enter a pattern ';return;}
let flags='';
if(document.getElementById('_rx-g').checked)flags+='g';
if(document.getElementById('_rx-i').checked)flags+='i';
if(document.getElementById('_rx-m').checked)flags+='m';
try{
const re=new RegExp(pattern,flags);
const matches=[...input.matchAll(new RegExp(pattern,flags.includes('g')?flags:flags+'g'))];
if(!matches.length){result.innerHTML='No matches ';return;}
let out=''+matches.length+' match(es) ';
matches.forEach((m,i)=>{
out+='['+i+'] '+esc(m[0])+' ';
if(m.length>1){out+=' groups: '+m.slice(1).map(g=>esc(g||'')).join(', ')+' ';}
out+='
';
});
result.innerHTML=out;
}catch(e){result.innerHTML='Error: '+esc(e.message)+' ';}
};
}
function showPythonRef(){
const cmds={
'Strings':['s.split(",")', 's.join(list)', 's.strip()', 's.replace(old, new)', 's.startswith("x")', 'f"Hello {name}"', 's.upper() / s.lower()', 's.find("x") / s.index("x")'],
'Lists':['lst.append(x)', 'lst.extend([1,2])', 'lst.insert(i, x)', 'lst.pop() / lst.pop(i)', 'lst.sort() / sorted(lst)', 'lst.reverse()', '[x for x in lst if cond]', 'list(map(fn, lst))'],
'Dicts':['d.get(k, default)', 'd.keys() / d.values() / d.items()', 'd.update({k:v})', 'd.pop(k)', '{k:v for k,v in items}', 'dict(zip(keys, vals))'],
'Files':['with open("f.txt") as f: data = f.read()', 'with open("f.txt","w") as f: f.write(s)', 'Path("dir").glob("*.py")', 'os.path.exists(p)', 'shutil.copy(src, dst)'],
'Stdlib':['import json; json.dumps(obj)', 'import datetime; datetime.now()', 'import re; re.findall(pat, s)', 'import os; os.environ["KEY"]', 'import sys; sys.argv', 'from collections import Counter, defaultdict'],
'Common':['try: ... except Exception as e: ...', 'if __name__ == "__main__":', 'lambda x: x*2', 'enumerate(lst)', 'zip(a, b)', 'isinstance(x, int)', '*args, **kwargs']
};
let html='';
html+='
Python Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskGoalTracker(){
if(!S._goals)S._goals=[];
let html='';
html+='
Goal Tracker X ';
html+='
Add
';
S._goals.forEach((g,i)=>{
const pct=g.target?Math.min(100,Math.round(g.current/g.target*100)):0;
const color=pct>=100?'#4ade80':pct>=50?'#fbbf24':'#06b6d4';
html+='
';
html+='
'+esc(g.title)+' '+g.current+'/'+g.target+' ('+pct+'%)
';
html+='
';
html+='
';
html+='- ';
html+='+ ';
html+=' ';
html+='x ';
html+='
';
});
if(!S._goals.length)html+='
No goals set. Add your first goal above.
';
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
window._goalAdd=function(){
const title=document.getElementById('_goal-title').value.trim();
const target=parseInt(document.getElementById('_goal-target').value)||10;
if(!title)return;
S._goals.push({title,target,current:0,createdAt:new Date().toISOString()});
save();
document.querySelector('div[style*=fixed]').remove();
showTaskGoalTracker();
};
}
function showQuickDiffViewer(){
let w=document.getElementById('diff-viewer-widget');if(w)w.remove();
w=document.createElement('div');w.id='diff-viewer-widget';
w.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:700px;width:95vw;max-height:80vh;overflow-y:auto';
let h='
Text Diff Viewer X ';
h+='';
h+='';
h+='';
h+='
';
h+='Compare ';
h+='
';
w.innerHTML=h;
document.body.appendChild(w);
window._diffCompare=function(){
const a=document.getElementById('_diff-a').value.split('\\n');
const b=document.getElementById('_diff-b').value.split('\\n');
const result=document.getElementById('_diff-result');
let html='';
const maxLen=Math.max(a.length,b.length);
for(let i=0;i '+esc(lineA)+'';
}else if(!lineA&&lineB){
html+='+'+esc(lineB)+'
';
}else if(lineA&&!lineB){
html+='-'+esc(lineA)+'
';
}else{
html+='-'+esc(lineA)+'
';
html+='+'+esc(lineB)+'
';
}
}
result.innerHTML=html||'No differences ';
};
}
function showTypeScriptRef(){
const cmds={
'Basic Types':['let x: string = "hello"', 'let n: number = 42', 'let b: boolean = true', 'let a: string[] = ["a","b"]', 'let t: [string, number] = ["a", 1]', 'let o: {name: string; age: number}'],
'Utility Types':['Partial', 'Required', 'Readonly', 'Pick', 'Omit', 'Record', 'ReturnType', 'Parameters'],
'Generics':['function identity(arg: T): T { return arg; }', 'interface Box { value: T; }', 'type Result = { ok: true; data: T } | { ok: false; error: E }'],
'Guards':['typeof x === "string"', 'x instanceof MyClass', 'function isString(x: unknown): x is string', '"key" in obj', 'x !== null && x !== undefined'],
'Advanced':['type Union = A | B', 'type Intersection = A & B', 'keyof T', 'T[K]', 'as const', 'satisfies Type', 'infer R'],
'Config':['strict: true', 'target: "ES2022"', 'module: "ESNext"', 'moduleResolution: "bundler"', 'paths: {"@/*": ["./src/*"]}']
};
let html='';
html+='
TypeScript Reference X ';
Object.entries(cmds).forEach(([cat,list])=>{
html+='
'+cat+'
';
list.forEach(c=>{html+='
'+c+'
';});
html+='
';
});
html+='
';
document.body.insertAdjacentHTML('beforeend',html);
}
function showTaskWIPBoard(){
const wip=(S.tasks||[]).filter(t=>t.status==='in-progress');
let html='';
html+='
Work In Progress ('+wip.length+') X ';
if(wip.length>5)html+='
WIP limit exceeded! Max 5 recommended. Currently: '+wip.length+'
';
if(!wip.length){html+='
No tasks in progress
';document.body.insertAdjacentHTML('beforeend',html);return;}
wip.forEach(t=>{
const pColor=t.priority==='p0'?'#ef4444':t.priority==='p1'?'#f97316':t.priority==='p2'?'#3b82f6':'#6b7280';
const age=t.createdAt?Math.ceil((new Date()-new Date(t.createdAt))/(1000*60*60*24)):0;
html+='';
html+='
'+esc(t.title)+' '+age+'d old
';
if(t.project)html+='
'+esc(t.project)+'
';
if(t.description)html+='
'+esc(t.description.substring(0,80))+'
';
html+='
';
});
html+='';
document.body.insertAdjacentHTML('beforeend',html);
}
function showQuickScreenRecorder(){
let w=document.getElementById('screen-rec-widget');if(w)w.remove();
w=document.createElement('div');w.id='screen-rec-widget';
w.style.cssText='position:fixed;bottom:20px;right:20px;z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:16px;box-shadow:0 8px 32px rgba(0,0,0,0.6);width:260px';
let h='
Screen Record Helper X ';
h+='00:00
';
h+='';
h+='Start Timer ';
h+='Stop ';
h+='
';
h+='Use OS screen recording tools. This timer helps track duration.
';
w.innerHTML=h;
document.body.appendChild(w);
window._srSeconds=0;
window._srInterval=null;
window._srStart=function(){
if(window._srInterval)return;
window._srSeconds=0;
document.getElementById('_sr-start').textContent='Recording...';
document.getElementById('_sr-start').style.background='#ef4444';
window._srInterval=setInterval(()=>{
window._srSeconds++;
const m=Math.floor(window._srSeconds/60);
const s=window._srSeconds%60;
document.getElementById('_sr-time').textContent=String(m).padStart(2,'0')+':'+String(s).padStart(2,'0');
},1000);
};
window._srStop=function(){
if(window._srInterval){clearInterval(window._srInterval);window._srInterval=null;}
document.getElementById('_sr-start').textContent='Start Timer';
document.getElementById('_sr-start').style.background='#4ade80';
};
}
function showProjectRoadmap(filterProject){
let panel=document.getElementById('roadmap-panel');if(panel)panel.remove();
panel=document.createElement('div');panel.id='roadmap-panel';
panel.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:600px;width:90vw;max-height:75vh;overflow-y:auto';
let tasks=S.tasks.filter(t=>t.due);
if(filterProject)tasks=tasks.filter(t=>t.project===filterProject);
tasks.sort((a,b)=>(a.due||'').localeCompare(b.due||''));
const projects=[...new Set(tasks.map(t=>t.project||'No Project'))];
const pColors=['#3b82f6','#8b5cf6','#f59e0b','#ef4444','#06b6d4','#ec4899','#22c55e','#f97316'];
const pColorMap={};projects.forEach((p,i)=>pColorMap[p]=pColors[i%pColors.length]);
const today=new Date().toISOString().split('T')[0];
let h='';
const months={};
tasks.forEach(t=>{const m=t.due.substring(0,7);if(!months[m])months[m]=[];months[m].push(t);});
Object.keys(months).sort().forEach(m=>{
const d=new Date(m+'-01');
const label=d.toLocaleDateString('en-US',{month:'long',year:'numeric'});
h+=`${label} (${months[m].length} tasks)
`;
months[m].forEach(t=>{
const clr=pColorMap[t.project||'No Project'];
const isDone=t.status==='done';const isOverdue=t.due${t.due.substring(5)} ${esc(t.title||'Untitled')} ${t.project?`${esc(t.project)} `:''}${t.priority||'p2'} `;
});
});
if(!tasks.length)h='No tasks with due dates'+(filterProject?' in '+filterProject:'')+'
';
const legend=projects.map(p=>` ${esc(p)} `).join(' ');
panel.innerHTML=`Project Roadmap${filterProject?' - '+esc(filterProject):''} ×
${legend}
${h}`;
document.body.appendChild(panel);
}
function addTaskColorLabel(taskId,color){
const t=S.tasks.find(x=>x.id===taskId);if(!t)return;
if(!t.labels)t.labels=[];
if(t.labels.includes(color)){t.labels=t.labels.filter(c=>c!==color);}
else{t.labels.push(color);if(t.labels.length>4)t.labels.shift();}
save();renderTasks();
}
function showBurndownChart(days){
days=days||14;
let panel=document.getElementById('burndown-panel');if(panel)panel.remove();
panel=document.createElement('div');panel.id='burndown-panel';
panel.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:560px;width:90vw';
const w=500,h=260,pad=40,gw=w-pad*2,gh=h-pad*2;
const today=new Date();const dates=[];
for(let i=days-1;i>=0;i--){const d=new Date(today);d.setDate(d.getDate()-i);dates.push(d.toISOString().split('T')[0]);}
const created=dates.map(ds=>S.tasks.filter(t=>t.created&&t.created.startsWith(ds)).length);
const completed=dates.map(ds=>S.tasks.filter(t=>t.completedAt&&t.completedAt.startsWith(ds)).length);
const maxVal=Math.max(1,...created,...completed);
const barW=Math.floor(gw/dates.length*0.35);
let svg=``;
// grid lines
for(let i=0;i<=4;i++){const y=pad+gh-gh*(i/4);const v=Math.round(maxVal*(i/4));svg+=`${v} `;}
// bars
dates.forEach((ds,i)=>{
const x=pad+i*(gw/dates.length)+2;
const ch=created[i]?(created[i]/maxVal)*gh:0;
const dh=completed[i]?(completed[i]/maxVal)*gh:0;
svg+=`${ds}: ${created[i]} created `;
svg+=`${ds}: ${completed[i]} completed `;
if(i%Math.ceil(days/7)===0||i===dates.length-1){svg+=`${ds.substring(5)} `;}
});
// legend
svg+=`Created `;
svg+=`Completed `;
// totals
const totalCreated=created.reduce((a,v)=>a+v,0);const totalCompleted=completed.reduce((a,v)=>a+v,0);
svg+=`${totalCreated} created, ${totalCompleted} completed (${days}d) `;
svg+=` `;
panel.innerHTML=`Task Burndown (${days} days) ×
${svg}
7d 14d 30d 90d
`;
document.body.appendChild(panel);
}
function checkDeadLinks(){
const links=S.links.filter(l=>l.url&&l.url.startsWith('http'));
if(!links.length){toast('No links to check');return;}
let panel=document.getElementById('deadlinks-panel');if(panel)panel.remove();
panel=document.createElement('div');panel.id='deadlinks-panel';
panel.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:500px;width:90vw;max-height:70vh;overflow-y:auto';
panel.innerHTML=`Checking ${links.length} Links... ×
0/${links.length} checked
`;
document.body.appendChild(panel);
let checked=0;const results=[];const batch=5;
async function checkBatch(start){
const slice=links.slice(start,start+batch);
await Promise.allSettled(slice.map(async l=>{
try{const r=await fetch(l.url,{method:'HEAD',mode:'no-cors',signal:AbortSignal.timeout(5000)});results.push({url:l.url,title:l.title,status:'ok',code:r.status||'opaque'});}
catch(e){results.push({url:l.url,title:l.title,status:'error',error:e.message||'timeout'});}
checked++;document.getElementById('deadlinks-progress').textContent=checked+'/'+links.length+' checked';
}));
const resEl=document.getElementById('deadlinks-results');
const broken=results.filter(r=>r.status==='error');
const ok=results.filter(r=>r.status==='ok');
resEl.innerHTML=(broken.length?`${broken.length} Broken/Unreachable
`+broken.map(r=>`x ${esc(r.title)} ${esc(r.url)} - ${esc(r.error)}
`).join(''):'')+(ok.length?`${ok.length} OK
`:'')+(checked===links.length?`Done. ${broken.length} broken, ${ok.length} ok out of ${links.length} total.
`:'');
if(start+batchcheckBatch(start+batch),200);
else{document.getElementById('deadlinks-progress').textContent='Complete: '+checked+'/'+links.length;document.querySelector('#deadlinks-panel > div:first-child > span').textContent='Link Health: '+broken.length+' broken, '+ok.length+' ok';}
}
checkBatch(0);
}
function enableDesktopNotifications(){
if(!('Notification' in window)){toast('Browser does not support notifications');return;}
if(Notification.permission==='granted'){toast('Notifications already enabled');checkOverdueNotify();return;}
if(Notification.permission==='denied'){toast('Notifications blocked. Enable in browser settings.');return;}
Notification.requestPermission().then(perm=>{if(perm==='granted'){toast('Notifications enabled');checkOverdueNotify();S._notificationsEnabled=true;save();}else toast('Notifications denied');});
}
function checkOverdueNotify(){
if(!('Notification' in window)||Notification.permission!=='granted')return;
const today=new Date().toISOString().split('T')[0];
const overdue=S.tasks.filter(t=>t.due&&t.due1?'s':'')+': '+overdue.slice(0,3).map(t=>t.title).join(', '),icon:'planet-logo.png'});}
}
function notifyFocusComplete(taskName){
if(!('Notification' in window)||Notification.permission!=='granted')return;
new Notification('Focus Session Complete',{body:taskName?'Finished: '+taskName:'Timer done! Take a break.',icon:'planet-logo.png'});
}
function showChart(type){
let panel=document.getElementById('chart-panel');if(panel)panel.remove();
panel=document.createElement('div');panel.id='chart-panel';
panel.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:500px;width:90vw';
let svg='';const w=400,h=250;
if(type==='status'){
const counts={todo:0,progress:0,done:0,blocked:0};S.tasks.forEach(t=>counts[t.status]=(counts[t.status]||0)+1);
const total=Object.values(counts).reduce((a,v)=>a+v,0);if(!total){panel.innerHTML='No tasks yet
Close ';document.body.appendChild(panel);return;}
const colors={todo:'#3b82f6',progress:'#f59e0b',done:'#4ade80',blocked:'#ef4444'};
let startAngle=-Math.PI/2;const cx=120,cy=120,r=100;
svg=``;
Object.entries(counts).filter(([,v])=>v>0).forEach(([status,count])=>{
const angle=(count/total)*Math.PI*2;const endAngle=startAngle+angle;
const x1=cx+r*Math.cos(startAngle),y1=cy+r*Math.sin(startAngle);
const x2=cx+r*Math.cos(endAngle),y2=cy+r*Math.sin(endAngle);
const large=angle>Math.PI?1:0;
svg+=`${status}: ${count} (${Math.round(count/total*100)}%) `;
startAngle=endAngle;
});
let ly=20;Object.entries(counts).filter(([,v])=>v>0).forEach(([s,c])=>{svg+=`${s}: ${c} (${Math.round(c/total*100)}%) `;ly+=20;});
svg+=' ';
}else if(type==='priority'){
const counts={p0:0,p1:0,p2:0,p3:0};S.tasks.filter(t=>t.status!=='done').forEach(t=>counts[t.priority||'p2']++);
const max=Math.max(...Object.values(counts),1);const colors={p0:'#ef4444',p1:'#f59e0b',p2:'#3b82f6',p3:'#666'};
svg=``;
Object.entries(counts).forEach(([p,c],i)=>{const bw=60,bh=Math.round(c/max*150),x=40+i*90,y=180-bh;
svg+=`${p.toUpperCase()} ${c} `;
});svg+=' ';
}else if(type==='theme'){
const themes={};S.content.forEach(c=>{const t=c.theme||'unthemed';themes[t]=(themes[t]||0)+1;});
const sorted=Object.entries(themes).sort((a,b)=>b[1]-a[1]).slice(0,8);const max=sorted.length?sorted[0][1]:1;
const cl=['#4ade80','#22d3ee','#a855f7','#f59e0b','#3b82f6','#ec4899','#ef4444','#eab308'];
svg=``;
sorted.forEach(([t,c],i)=>{const bw=Math.round(c/max*(w-140)),y=5+i*28;
svg+=`${esc(t)} (${c}) `;
});svg+=' ';
}else if(type==='weekly'){
const days=[];const today=new Date();
for(let i=6;i>=0;i--){const d=new Date(today);d.setDate(d.getDate()-i);const ds=d.toISOString().split('T')[0];days.push({label:['Su','Mo','Tu','We','Th','Fr','Sa'][d.getDay()],created:S.tasks.filter(t=>t.created&&t.created.startsWith(ds)).length,completed:S.tasks.filter(t=>t.completedAt&&t.completedAt.startsWith(ds)).length,content:S.content.filter(c=>c.created&&c.created.startsWith(ds)).length});}
const max=Math.max(...days.map(d=>d.created+d.completed+d.content),1);
svg=``;
days.forEach((d,i)=>{const x=30+i*52,bw=14;
svg+=`${d.label} `;
});
svg+=`Created Done Content `;
}
panel.innerHTML=`${{status:'Task Status',priority:'Task Priority (Active)',theme:'Content Themes',weekly:'Weekly Activity'}[type]} ×
${svg}
`;
document.body.appendChild(panel);
}
function toggleScratchpad(){
let panel=document.getElementById('scratchpad-panel');
if(panel){panel.style.display=panel.style.display==='none'?'flex':'none';if(panel.style.display==='flex')panel.querySelector('textarea').focus();return;}
panel=document.createElement('div');panel.id='scratchpad-panel';
panel.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1400;width:400px;max-width:90vw;height:300px;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:12px;display:flex;flex-direction:column;gap:8px;box-shadow:0 12px 48px rgba(0,0,0,0.6);resize:both;overflow:hidden';
panel.innerHTML=``;
document.body.appendChild(panel);panel.querySelector('textarea').focus();
}
function showActivityHeatmap(){
let panel=document.getElementById('heatmap-panel');if(panel)panel.remove();
panel=document.createElement('div');panel.id='heatmap-panel';
panel.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:1500;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:20px;box-shadow:0 12px 48px rgba(0,0,0,0.7);max-width:720px;width:90vw';
const today=new Date();const cells=[];
for(let i=89;i>=0;i--){
const d=new Date(today);d.setDate(d.getDate()-i);const ds=d.toISOString().split('T')[0];
const count=S.tasks.filter(t=>(t.completedAt&&t.completedAt.startsWith(ds))||(t.created&&t.created.startsWith(ds))).length+S.content.filter(c=>c.created&&c.created.startsWith(ds)).length+S.docs.filter(doc=>(doc.updated||doc.created||'').startsWith(ds)).length;
const lvl=count===0?0:count<=2?1:count<=5?2:count<=10?3:4;
const colors=['#161619','#0e4429','#006d32','#26a641','#39d353'];
cells.push(`
`);
}
const totalAct=cells.reduce((a,c,i)=>{const m=c.match(/: (\d+)/);return a+parseInt(m?m[1]:0);},0);
panel.innerHTML=`90-Day Activity Heatmap ×
${cells.join('')}
`;
document.body.appendChild(panel);
}
function cmdSearch() {
const q = document.getElementById('cmd-input').value;
const items = cmdGetItems(q);
cmdIdx = 0;
const el = document.getElementById('cmd-results');
if(!items.length) { el.innerHTML = 'No results
'; return; }
el.innerHTML = (q?`${items.length} result${items.length!==1?'s':''}
`:'')+items.map((it, i) => {
const iconHtml = it.icon.startsWith('<') ? it.icon : `${it.icon} `;
return `
${iconHtml}
${esc(it.title)}
${esc(it.desc||'')}
${it.type}
`;
}).join('');
}
function cmdHover(i) { cmdIdx = i; cmdHighlight(); }
function cmdHighlight() {
document.querySelectorAll('.cmd-item').forEach((el, i) => el.classList.toggle('active', i === cmdIdx));
const active = document.querySelector('.cmd-item.active');
if(active) active.scrollIntoView({block:'nearest'});
}
function cmdKeydown(e) {
const items = document.querySelectorAll('.cmd-item');
if(e.key === 'ArrowDown') { e.preventDefault(); cmdIdx = Math.min(cmdIdx + 1, items.length - 1); cmdHighlight(); }
else if(e.key === 'ArrowUp') { e.preventDefault(); cmdIdx = Math.max(cmdIdx - 1, 0); cmdHighlight(); }
else if(e.key === 'Enter') { e.preventDefault(); cmdExec(cmdIdx); }
else if(e.key === 'Escape') { closeCommandPalette(); }
}
function cmdExec(idx) {
const items = cmdGetItems(document.getElementById('cmd-input').value);
if(items[idx] && items[idx].action) { closeCommandPalette(); items[idx].action(); }
}
// === MODE SWITCHING ===
let currentMode = 'default';
function setMode(mode) {
currentMode = mode;
const app = document.querySelector('.app');
app.classList.remove('mode-focus', 'mode-extended');
// Close project panel in focus mode — no sidebar means no way to navigate
if(mode === 'focus') {
app.classList.add('mode-focus');
if(app.classList.contains('project-open')) closeProjectPanel();
app.classList.remove('context-open');
}
if(mode === 'extended') {
app.classList.add('mode-extended');
if(app.classList.contains('project-open')) closeProjectPanel();
if(!app.classList.contains('context-open')) app.classList.add('context-open');
updateContextStats();
}
if(mode === 'default') {
app.classList.remove('context-open');
}
document.querySelectorAll('.mode-btn').forEach(b => b.classList.remove('active'));
document.getElementById('mode-'+mode+'-btn').classList.add('active');
}
// === SIDEBAR TOGGLE ===
function toggleSidebar() {
const app = document.querySelector('.app');
app.classList.toggle('sidebar-collapsed');
localStorage.setItem('sidebar-collapsed', app.classList.contains('sidebar-collapsed') ? '1' : '');
}
function openMobileSidebar(){document.querySelector('.sidebar').classList.add('mobile-open');document.getElementById('mobile-overlay').classList.add('open');}
function closeMobileSidebar(){document.querySelector('.sidebar').classList.remove('mobile-open');document.getElementById('mobile-overlay').classList.remove('open');}
// === CONTEXT PANEL ===
function toggleContextPanel() {
const app = document.querySelector('.app');
if(app.classList.contains('project-open')) {
closeProjectPanel();
}
app.classList.toggle('context-open');
updateContextStats();
}
// === PANEL RESIZING ===
(function initResize() {
document.addEventListener('DOMContentLoaded', () => {
const sidebarHandle = document.getElementById('sidebar-resize');
const contextHandle = document.getElementById('context-resize');
const root = document.documentElement;
let resizing = null;
function onMouseDown(e, type) {
e.preventDefault();
resizing = type;
document.body.style.cursor = 'col-resize';
document.body.style.userSelect = 'none';
const handle = type === 'sidebar' ? sidebarHandle : contextHandle;
if(handle) handle.classList.add('dragging');
}
if(sidebarHandle) sidebarHandle.addEventListener('mousedown', e => onMouseDown(e, 'sidebar'));
if(contextHandle) contextHandle.addEventListener('mousedown', e => onMouseDown(e, 'context'));
document.addEventListener('mousemove', e => {
if(!resizing) return;
if(resizing === 'sidebar') {
const w = Math.max(160, Math.min(400, e.clientX));
root.style.setProperty('--sidebar-width', w + 'px');
} else if(resizing === 'context') {
const w = Math.max(200, Math.min(500, window.innerWidth - e.clientX));
root.style.setProperty('--context-width', w + 'px');
}
});
document.addEventListener('mouseup', () => {
if(!resizing) return;
const handle = resizing === 'sidebar' ? sidebarHandle : contextHandle;
if(handle) handle.classList.remove('dragging');
resizing = null;
document.body.style.cursor = '';
document.body.style.userSelect = '';
});
});
})();
function updateContextStats() {
const activeTasks = S.tasks.filter(t => t.status !== 'done').length;
const el = id => { const e = document.getElementById(id); if(e) return e; return {textContent:''}; };
el('ctx-stat-tasks').textContent = activeTasks;
el('ctx-stat-docs').textContent = S.docs.length + S.specs.length;
el('ctx-stat-projects').textContent = (S.projects||[]).length;
el('ctx-stat-kb').textContent = (S.knowledgeBase||[]).length;
updateContextRelated();
renderGraph();
}
function updateContextRelated() {
const el = document.getElementById('ctx-related-items');
if(!el) return;
let html = '';
if(currentSection === 'writer') {
const doc = getActiveDoc();
if(doc && doc.title) {
const backlinks = getBacklinks('doc', doc.title);
if(backlinks.length) {
html += 'Backlinks to "' + esc(doc.title) + '":
';
backlinks.forEach(bl => {
html += '' + bl.type[0].toUpperCase() + ' ' + esc(bl.title) + '
';
});
}
}
} else if(currentSection === 'specs') {
const spec = getActiveSpec();
if(spec && spec.title) {
const backlinks = getBacklinks('spec', spec.title);
if(backlinks.length) {
html += 'Backlinks to "' + esc(spec.title) + '":
';
backlinks.forEach(bl => {
html += '' + bl.type[0].toUpperCase() + ' ' + esc(bl.title) + '
';
});
}
}
} else if(currentSection === 'tasks') {
// Show overdue tasks
const today = new Date().toISOString().split('T')[0];
const overdue = S.tasks.filter(t => t.due && t.due < today && t.status !== 'done');
if(overdue.length) {
html += 'Overdue (' + overdue.length + '):
';
overdue.slice(0, 5).forEach(t => {
html += '! ' + esc(t.title || 'Untitled') + '
';
});
}
// Show today's tasks
const todayTasks = S.tasks.filter(t => t.due === today && t.status !== 'done');
if(todayTasks.length) {
html += 'Today (' + todayTasks.length + '):
';
todayTasks.forEach(t => {
html += '* ' + esc(t.title || 'Untitled') + '
';
});
}
}
if(!html) html = 'No related items for current view
';
el.innerHTML = html;
}
// === FOCUS TIMER (Embedded) ===
let ftDuration = 1500, ftTimeLeft = 1500, ftRunning = false, ftPaused = false, ftInterval = null;
let ftCategory = 'Writing', ftColor = '#4ade80';
function ftToggle() {
if(!ftRunning && !ftPaused) ftStart();
else if(ftRunning) ftPause();
else ftResume();
}
let ftTaskId=null;
function ftStartForTask(id){
const t=S.tasks.find(x=>x.id===id);if(!t)return;
ftTaskId=id;
ftSetCat(null,t.title.substring(0,20)||'Task','#4ade80');
ftReset();
if(!document.querySelector('.app').classList.contains('context-open'))toggleContextPanel();
closeTaskDetail();
ftToggle();
if(!t.timeStarted){t.timeStarted=new Date().toISOString();if(t.status==='todo'){t.status='progress';if(!t.log)t.log=[];t.log.push({from:'todo',to:'progress',at:t.timeStarted});}save();}
toast('Focus timer started for: '+t.title.substring(0,30));
}
function ftStart() {
ftRunning = true; ftPaused = false;
document.getElementById('ft-btn').textContent = 'Pause';
document.getElementById('ft-btn').classList.add('running');
document.getElementById('ft-time-adjust').style.opacity = '0.3';
ftInterval = setInterval(() => {
ftTimeLeft--;
ftUpdateDisplay();
if(ftTimeLeft <= 0) ftComplete();
}, 1000);
}
function ftPause() {
ftRunning = false; ftPaused = true;
clearInterval(ftInterval);
document.getElementById('ft-btn').textContent = 'Resume';
document.getElementById('ft-btn').classList.remove('running');
}
function ftResume() { ftStart(); }
function ftComplete() {
ftRunning = false; ftPaused = false;
clearInterval(ftInterval);
document.getElementById('ft-btn').textContent = 'Done!';
document.getElementById('ft-btn').classList.remove('running');
ftPlaySound();
setTimeout(ftReset, 3000);
}
function ftReset() {
ftRunning = false; ftPaused = false;
clearInterval(ftInterval);
ftTimeLeft = ftDuration;
document.getElementById('ft-btn').textContent = 'Start';
document.getElementById('ft-btn').classList.remove('running');
document.getElementById('ft-time-adjust').style.opacity = '1';
ftUpdateDisplay();
}
function ftUpdateDisplay() {
const m = Math.floor(ftTimeLeft / 60), s = ftTimeLeft % 60;
document.getElementById('ft-time').textContent = m + ':' + String(s).padStart(2, '0');
const progress = 1 - (ftTimeLeft / ftDuration);
const circumference = 2 * Math.PI * 70;
const offset = circumference * (1 - progress);
const prog = document.getElementById('ft-progress');
if(prog) { prog.style.strokeDasharray = circumference; prog.style.strokeDashoffset = offset; prog.style.stroke = ftColor; }
}
function ftAdjust(min) {
if(ftRunning || ftPaused) return;
ftDuration = Math.max(300, Math.min(7200, ftDuration + min * 60));
ftTimeLeft = ftDuration;
document.getElementById('ft-duration-label').textContent = Math.floor(ftDuration / 60) + ' min';
ftUpdateDisplay();
}
function ftSetCat(el, name, color) {
ftCategory = name; ftColor = color;
document.querySelectorAll('.ft-cat').forEach(c => c.classList.remove('active'));
el.classList.add('active');
document.getElementById('ft-label').textContent = name;
ftUpdateDisplay();
}
function ftPlaySound() {
try {
const ctx = new (window.AudioContext || window.webkitAudioContext)();
const osc = ctx.createOscillator(), gain = ctx.createGain();
osc.connect(gain); gain.connect(ctx.destination);
osc.frequency.setValueAtTime(800, ctx.currentTime);
osc.frequency.setValueAtTime(600, ctx.currentTime + 0.1);
osc.frequency.setValueAtTime(800, ctx.currentTime + 0.2);
gain.gain.setValueAtTime(0.3, ctx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.5);
osc.start(ctx.currentTime); osc.stop(ctx.currentTime + 0.5);
} catch(e) {}
}
// === CLOUD SYNC (Vercel Blob Backend) ===
const ASTRA_API = window.location.origin;
let ASTRA_ADMIN_PW = localStorage.getItem('astra_admin_pw') || '';
let cloudSyncTimer = null;
let lastCloudSync = 0;
const CLOUD_SYNC_INTERVAL = 30000;
function ensureAdminPW() {
if (ASTRA_ADMIN_PW) return true;
var pw = prompt('Enter ASTRA admin password for cloud sync:');
if (!pw) return false;
ASTRA_ADMIN_PW = pw;
localStorage.setItem('astra_admin_pw', pw);
return true;
}
function setCloudIndicator(state) {
const el = document.getElementById('cloud-sync-indicator');
if(!el) return;
if(state==='syncing') { el.style.opacity='1'; el.style.color='var(--accent-cyan)'; el.title='Syncing...'; }
else if(state==='synced') { el.style.opacity='0.7'; el.style.color='var(--green)'; el.title='Synced '+(new Date().toLocaleTimeString())+' — click to sync'; }
else if(state==='error') { el.style.opacity='0.8'; el.style.color='var(--red)'; el.title='Sync failed — click to retry'; }
else { el.style.opacity='0.4'; el.style.color='var(--text-muted)'; el.title='Not synced — click to sync'; }
}
async function cloudSave(silent) {
if (!ASTRA_ADMIN_PW && silent) return { ok: false };
if (!ensureAdminPW()) return { ok: false };
setCloudIndicator('syncing');
try {
const state = JSON.parse(localStorage.getItem(SK) || '{}');
const res = await fetch(ASTRA_API + '/api/state', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + ASTRA_ADMIN_PW },
body: JSON.stringify(state)
});
const data = await res.json();
if (data.ok) {
lastCloudSync = Date.now();
setCloudIndicator('synced');
if (!silent) toast('Synced to cloud (v' + data.version + ')');
} else if (data.error === 'Unauthorized') {
localStorage.removeItem('astra_admin_pw');
ASTRA_ADMIN_PW = '';
setCloudIndicator('error');
if (!silent) toast('Wrong password. Try Cmd+S again.');
} else {
setCloudIndicator('error');
}
return data;
} catch(e) { setCloudIndicator('error'); if (!silent) toast('Cloud sync error: ' + e.message); return { ok: false }; }
}
function scheduleCloudSync() {
if (cloudSyncTimer) clearTimeout(cloudSyncTimer);
cloudSyncTimer = setTimeout(function() { cloudSave(true); }, CLOUD_SYNC_INTERVAL);
}
async function cloudLoad() {
if (!ensureAdminPW()) return;
try {
const res = await fetch(ASTRA_API + '/api/state', {
headers: { 'Authorization': 'Bearer ' + ASTRA_ADMIN_PW }
});
const data = await res.json();
if (data._source === 'blob' && (data.projects || data.tasks || data.docs || data.content)) {
delete data._source; delete data._savedAt; delete data._version;
localStorage.setItem(SK, JSON.stringify(data));
location.reload();
} else if (data._source === 'none' || data._source === 'empty') {
toast('No cloud state yet — saving current state');
cloudSave(false);
} else { toast('No cloud state found'); }
} catch(e) { toast('Cloud load error: ' + e.message); }
}
async function logTranscript(text, source) {
try {
await fetch(ASTRA_API + '/api/transcripts', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + ASTRA_ADMIN_PW },
body: JSON.stringify({ text, source: source || 'astra-voice', tags: ['voice-input'] })
});
} catch(e) { /* silent fail for transcript logging */ }
}
async function queryAstra(type, params) {
try {
const res = await fetch(ASTRA_API + '/api/query', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + ASTRA_ADMIN_PW },
body: JSON.stringify({ type, ...params })
});
return await res.json();
} catch(e) { return { ok: false, error: e.message }; }
}
// === INIT ===
load();
seedLinks();
seedProjects();
migrateV2();
save();
if(localStorage.getItem('sidebar-collapsed')) document.querySelector('.app').classList.add('sidebar-collapsed');
initVoice();
wbLoadState();
renderContent();renderTasks();renderCalendar();renderWriter();renderSpecs();renderLinks();renderProjectsSidebar();renderFolderTree();updateStorage();
ftUpdateDisplay();updateContextStats();
document.getElementById('sidebar-date').textContent=new Date().toLocaleDateString('en-US',{weekday:'short',month:'short',day:'numeric'});
setTimeout(function(){ cloudSave(true); }, 3000);
setTimeout(function(){ if(S._notificationsEnabled) checkOverdueNotify(); }, 5000);
if(S._autoBackup) scheduleAutoBackup();
if(S._stickies&&S._stickies.length) renderStickyNotes();
// Whiteboard drop handler for KB items
document.getElementById('panel-whiteboard')?.addEventListener('drop', handleWbDrop);
document.getElementById('panel-whiteboard')?.addEventListener('dragover', e => { if(e.dataTransfer?.types?.includes('text/plain')) e.preventDefault(); });
document.querySelectorAll('.modal-overlay').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('open');}));
window.addEventListener('beforeunload',()=>{if(zenIsOpen)zenSnapshot();snapshotWriter();snapshotSpec();wbPersist();save();});
document.addEventListener('keydown',e=>{
// Command Palette: Cmd+K
if((e.metaKey||e.ctrlKey) && e.key==='k') { e.preventDefault(); openCommandPalette(); return; }
// Cmd+Shift+W: toggle Zen Writer
if((e.metaKey||e.ctrlKey) && e.shiftKey && (e.key==='w'||e.key==='W')) { e.preventDefault(); if(zenIsOpen) zenClose(); else zenOpen(); return; }
// Cmd+S: save (Zen Writer version save or workspace save)
if((e.metaKey||e.ctrlKey) && e.key==='s') { e.preventDefault(); if(zenIsOpen){ zenSaveVersion(); } else { snapshotWriter(); snapshotSpec(); wbPersist(); save(); cloudSave(); } return; }
// Cmd+Shift+S: toggle Scratchpad
if((e.metaKey||e.ctrlKey) && e.shiftKey && (e.key==='s'||e.key==='S')) { e.preventDefault(); toggleScratchpad(); return; }
// Skip shortcuts when typing in inputs
const inInput = e.target.tagName==='INPUT'||e.target.tagName==='TEXTAREA'||e.target.contentEditable==='true';
if(e.key==='Escape'){
if(zenIsOpen) { zenClose(); return; }
if(document.getElementById('task-detail-modal').classList.contains('open')) { closeTaskDetail(); return; }
if(document.getElementById('cmd-overlay').classList.contains('open')) { closeCommandPalette(); return; }
document.querySelectorAll('.modal-overlay.open').forEach(m=>m.classList.remove('open'));
if(activeProject) closeProjectPanel();
}
if(inInput) return;
// Priority shortcuts in task detail modal (1-4 for p0-p3)
if(document.getElementById('task-detail-modal').classList.contains('open')&&!e.metaKey&&!e.ctrlKey){
const pMap={'1':'p0','2':'p1','3':'p2','4':'p3'};
if(pMap[e.key]){document.getElementById('td-priority').value=pMap[e.key];toast('Priority: '+pMap[e.key].toUpperCase());return;}
if(e.key==='s'&&!e.shiftKey){saveTaskDetail();return;}
}
// Cmd+number: switch sections
if((e.metaKey||e.ctrlKey) && e.key>='1' && e.key<='9') {
e.preventDefault();
const sections = ['content','tasks','calendar','writer','specs','links','whiteboard','pipeline','repos'];
const idx = parseInt(e.key)-1;
if(sections[idx]) {
const items = document.querySelectorAll('.sidebar-item');
switchSection(sections[idx], items[idx]||null);
}
return;
}
// Cmd+Shift+N: quick capture
if((e.metaKey||e.ctrlKey) && e.shiftKey && e.key==='n') { e.preventDefault(); qcOpen(); return; }
// Cmd+Shift+T: new task from anywhere
if((e.metaKey||e.ctrlKey) && e.shiftKey && (e.key==='t'||e.key==='T')) { e.preventDefault(); switchSection('tasks',document.querySelectorAll('.sidebar-item')[1]||null); setTimeout(()=>addTask(),100); return; }
// Cmd+B: toggle sidebar
if((e.metaKey||e.ctrlKey) && e.key==='b' && !e.shiftKey) { e.preventDefault(); toggleSidebar(); return; }
// Cmd+Shift+D: today view
if((e.metaKey||e.ctrlKey) && e.shiftKey && (e.key==='d'||e.key==='D')) { e.preventDefault(); showTodayView(); return; }
// Cmd+Shift+F: toggle focus mode
if((e.metaKey||e.ctrlKey) && e.shiftKey && (e.key==='f'||e.key==='F')) { e.preventDefault(); const app=document.querySelector('.app');const isFocus=app.classList.contains('mode-focus');setMode(isFocus?'default':'focus'); return; }
// Cmd+Shift+W: open Zen Writer
if((e.metaKey||e.ctrlKey) && e.shiftKey && (e.key==='w'||e.key==='W')) { e.preventDefault(); zenOpen(); return; }
// Cmd+Shift+E: export current section
if((e.metaKey||e.ctrlKey) && e.shiftKey && (e.key==='e'||e.key==='E')) { e.preventDefault(); if(currentSection==='tasks')exportTasks();else if(currentSection==='content')exportContent();else if(currentSection==='links')exportLinks();else if(currentSection==='calendar')exportWeek();else if(currentSection==='writer'){writerExport('clipboard');}else toast('No export for this section'); return; }
// Cmd+D: duplicate current item (writer doc / spec)
if((e.metaKey||e.ctrlKey) && e.key==='d' && !e.shiftKey && currentSection==='writer') { e.preventDefault(); if(S.activeDoc)dupDoc(S.activeDoc); return; }
if((e.metaKey||e.ctrlKey) && e.key==='d' && !e.shiftKey && currentSection==='specs') { e.preventDefault(); if(S.activeSpec)dupSpec(S.activeSpec); return; }
// Cmd+N: new item in current section
if((e.metaKey||e.ctrlKey) && e.key==='n' && !e.shiftKey) {
e.preventDefault();
if(currentSection==='content') openContentModal();
else if(currentSection==='tasks') addTask();
else if(currentSection==='writer') newDoc();
else if(currentSection==='specs') newSpec();
else if(currentSection==='links') openLinkModal();
return;
}
// Cmd+Z: undo last delete (content)
if((e.metaKey||e.ctrlKey) && e.key==='z' && !e.shiftKey) { if(lastDeletedContent){e.preventDefault();undoDeleteContent();return;} if(lastDeletedLink){e.preventDefault();undoDeleteLink();return;} }
// Cmd+E: toggle context panel
if((e.metaKey||e.ctrlKey) && e.key==='e') { e.preventDefault(); toggleContextPanel(); return; }
// Cmd+\\: toggle focus mode
if((e.metaKey||e.ctrlKey) && e.key==='\\') { e.preventDefault(); setMode(currentMode==='focus'?'default':'focus'); return; }
// Cmd+/: show shortcuts help
if((e.metaKey||e.ctrlKey) && e.key==='/') { e.preventDefault(); document.getElementById('shortcuts-modal').classList.toggle('open'); return; }
});
// === RESIZE HANDLE FOR PROJECT PANEL ===
(function(){
const handle = document.getElementById('project-resize-handle');
const root = document.documentElement;
let dragging = false;
let startX, startWidth;
handle.addEventListener('mousedown', e => {
dragging = true;
handle.classList.add('dragging');
startX = e.clientX;
startWidth = document.getElementById('panel-project').offsetWidth;
document.body.style.cursor = 'col-resize';
document.body.style.userSelect = 'none';
e.preventDefault();
});
document.addEventListener('mousemove', e => {
if(!dragging) return;
const delta = startX - e.clientX;
const newWidth = Math.max(280, Math.min(800, startWidth + delta));
root.style.setProperty('--project-width', newWidth + 'px');
});
document.addEventListener('mouseup', () => {
if(!dragging) return;
dragging = false;
handle.classList.remove('dragging');
document.body.style.cursor = '';
document.body.style.userSelect = '';
});
})();
// === PIPELINE ===
let plRecorder=null, plChunks=[], plRecording=false, plRecStart=0, plRecTimer=null, plAudioBlob=null, plTranscriptText='', plSynthesisText='', plApiOk=null;
function plCheckApi(){
if(!ASTRA_ADMIN_PW){document.getElementById('pl-status-dot').style.background='var(--text-muted)';document.getElementById('pl-status-dot').title='No password set';document.getElementById('pl-onboarding').style.display='block';return;}
fetch(ASTRA_API+'/api/health',{headers:{'Authorization':'Bearer '+ASTRA_ADMIN_PW}}).then(r=>r.json()).then(d=>{
plApiOk=true;document.getElementById('pl-status-dot').style.background='var(--green)';document.getElementById('pl-status-dot').title='API connected';document.getElementById('pl-onboarding').style.display='none';
}).catch(()=>{
plApiOk=false;document.getElementById('pl-status-dot').style.background='var(--orange)';document.getElementById('pl-status-dot').title='API unreachable';document.getElementById('pl-onboarding').style.display='block';
});
}
function plSaveLocal(entry){if(!S.pipelineHistory)S.pipelineHistory=[];S.pipelineHistory.unshift(entry);if(S.pipelineHistory.length>50)S.pipelineHistory.length=50;save();}
function plToggleRecord() {
const btn=document.getElementById('pl-record-btn');
const indicator=document.getElementById('pl-recording');
if(plRecording && plRecorder && plRecorder.state==='recording') {
plRecorder.stop();
plRecording=false;
btn.textContent='Record Mic';
btn.classList.remove('active');
indicator.style.display='none';
clearInterval(plRecTimer);
toast('Processing audio...');
return;
}
navigator.mediaDevices.getUserMedia({audio:true}).then(stream => {
plChunks=[];
plRecorder=new MediaRecorder(stream,{mimeType:'audio/webm'});
plRecorder.ondataavailable=e=>{if(e.data.size>0)plChunks.push(e.data);};
plRecorder.onstop=()=>{
stream.getTracks().forEach(t=>t.stop());
plAudioBlob=new Blob(plChunks,{type:'audio/webm'});
const preview=document.getElementById('pl-input-preview');
preview.style.display='block';
preview.textContent='Audio recorded ('+Math.round(plAudioBlob.size/1024)+'KB). Ready to process.';
toast('Audio ready — set your prompt and hit Process');
};
plRecorder.start();
plRecording=true;
btn.textContent='Stop Recording';
btn.classList.add('active');
indicator.style.display='flex';
plRecStart=Date.now();
plRecTimer=setInterval(()=>{
document.getElementById('pl-rec-time').textContent='Recording... '+Math.floor((Date.now()-plRecStart)/1000)+'s';
},1000);
toast('Recording...');
}).catch(()=>toast('Mic access denied'));
}
function plUploadFile(input) {
const file=input.files[0];
if(!file) return;
plAudioBlob=file;
const preview=document.getElementById('pl-input-preview');
preview.style.display='block';
preview.textContent='File: '+file.name+' ('+Math.round(file.size/1024)+'KB). Ready to process.';
toast('Audio loaded — set your prompt and hit Process');
input.value='';
}
// Pipeline drop zone for text/audio files
(function(){
const panel=document.getElementById('panel-pipeline');
if(!panel)return;
panel.addEventListener('dragover',e=>{e.preventDefault();e.dataTransfer.dropEffect='copy';panel.style.outline='2px dashed var(--accent)';});
panel.addEventListener('dragleave',()=>{panel.style.outline='none';});
panel.addEventListener('drop',e=>{
e.preventDefault();panel.style.outline='none';
const file=e.dataTransfer.files[0];if(!file)return;
if(file.type.startsWith('audio/')){plAudioBlob=file;const p=document.getElementById('pl-input-preview');p.style.display='block';p.textContent='Audio: '+file.name+' ('+Math.round(file.size/1024)+'KB)';toast('Audio loaded');}
else if(file.type.startsWith('text/')||file.name.endsWith('.txt')||file.name.endsWith('.md')){
const r=new FileReader();r.onload=()=>{plAudioBlob=null;plTranscriptText=r.result;const p=document.getElementById('pl-input-preview');p.style.display='block';p.textContent=plTranscriptText.length>300?plTranscriptText.substring(0,300)+'...':plTranscriptText;toast('Text loaded from '+file.name);};r.readAsText(file);
}else{toast('Drop audio or text files');}
});
})();
function plPasteText() {
navigator.clipboard.readText().then(text=>{
if(!text){toast('Clipboard empty');return;}
plAudioBlob=null;
plTranscriptText=text;
const preview=document.getElementById('pl-input-preview');
preview.style.display='block';
const wc=text.trim().split(/\s+/).filter(x=>x.length).length;
preview.innerHTML=''+text.length+' chars / '+wc+' words
'+(text.length>300?esc(text.substring(0,300))+'...':esc(text));
toast('Text pasted — set your prompt and hit Process');
}).catch(()=>toast('Cannot read clipboard'));
}
async function plProcess() {
const prompt=document.getElementById('pl-prompt').value.trim();
if(!prompt){toast('Enter a prompt first');return;}
if(!plAudioBlob && !plTranscriptText){toast('Record, upload, or paste something first');return;}
const btn=document.getElementById('pl-process-btn');
btn.textContent='Processing...';
btn.disabled=true;
try {
const source=document.getElementById('pl-source').value;
let res;
if(plAudioBlob) {
const fd=new FormData();
fd.append('audio',plAudioBlob,plAudioBlob.name||'recording.webm');
fd.append('prompt',prompt);
fd.append('source',source);
res=await fetch(ASTRA_API+'/api/pipeline',{method:'POST',headers:{'Authorization':'Bearer '+ASTRA_ADMIN_PW},body:fd});
} else {
res=await fetch(ASTRA_API+'/api/pipeline',{method:'POST',headers:{'Content-Type':'application/json','Authorization':'Bearer '+ASTRA_ADMIN_PW},body:JSON.stringify({text:plTranscriptText,prompt:prompt,source:source})});
}
const data=await res.json();
if(data.ok) {
plTranscriptText=data.transcript||'';
plSynthesisText=data.synthesis||'';
const resultDiv=document.getElementById('pl-result');
resultDiv.style.display='block';
if(data.inputType==='audio'&&data.transcript) {
document.getElementById('pl-transcript-box').style.display='block';
document.getElementById('pl-transcript-text').textContent=data.transcript;
} else {
document.getElementById('pl-transcript-box').style.display='none';
}
document.getElementById('pl-synthesis-text').textContent=data.synthesis;
plUpdateResultStats(data.synthesis);
plSaveLocal({id:data.pipelineId||('p_'+Date.now()),inputType:data.inputType||'text',prompt:prompt,preview:(data.synthesis||'').substring(0,200),source:source,createdAt:new Date().toISOString()});
toast('Pipeline complete!');
} else {
toast('Error: '+(data.error||'unknown'));
}
} catch(e) {
// Fallback: local text processing if API unavailable
if(plTranscriptText){
const result=plLocalProcess(plTranscriptText,prompt);
plSynthesisText=result;
document.getElementById('pl-result').style.display='block';
document.getElementById('pl-transcript-box').style.display='none';
document.getElementById('pl-synthesis-text').textContent=result;
plUpdateResultStats(result);
plSaveLocal({id:'p_'+Date.now(),inputType:'text',prompt:prompt,preview:result.substring(0,200),source:document.getElementById('pl-source').value,createdAt:new Date().toISOString()});
toast('Processed locally (API unavailable)');
} else {
toast('Pipeline error: '+e.message);
}
} finally {
btn.textContent='Process Pipeline';
btn.disabled=false;
}
}
function plLocalProcess(text,prompt){
const words=text.trim().split(/\s+/).filter(x=>x.length);
const sentences=text.split(/[.!?]+/).map(s=>s.trim()).filter(Boolean);
const pl=prompt.toLowerCase();
if(pl.includes('summar')){return'Summary (local):\n\n'+sentences.slice(0,Math.min(5,Math.ceil(sentences.length/3))).map(s=>'- '+s+'.').join('\n')+'\n\nStats: '+words.length+' words, '+sentences.length+' sentences.';}
if(pl.includes('action')||pl.includes('task')||pl.includes('checklist')){const actions=sentences.filter(s=>/\b(need|must|should|will|todo|action|fix|add|create|build|update|check|review|send|schedule)\b/i.test(s));return'Action Items (local):\n\n'+(actions.length?actions.map(a=>'[ ] '+a+'.').join('\n'):'No explicit action items found.\n\nAll sentences:\n'+sentences.map(s=>'[ ] '+s+'.').join('\n'));}
if(pl.includes('clean')||pl.includes('grammar')){return text.replace(/\s+/g,' ').replace(/\s([,.!?;:])/g,'$1').replace(/([.!?])\s*/g,'$1 ').trim();}
if(pl.includes('count')||pl.includes('stat')){const chars=text.length;const paras=text.split(/\n\s*\n/).filter(Boolean).length;const uniq=[...new Set(words.map(w=>w.toLowerCase()))].length;return'Text Statistics:\n\nWords: '+words.length+'\nCharacters: '+chars+'\nSentences: '+sentences.length+'\nParagraphs: '+paras+'\nUnique words: '+uniq+'\nAvg words/sentence: '+Math.round(words.length/Math.max(1,sentences.length))+'\nReading time: '+Math.max(1,Math.ceil(words.length/238))+' min';}
if(pl.includes('keyword')||pl.includes('frequent')||pl.includes('top word')){const freq={};words.forEach(w=>{const lw=w.toLowerCase().replace(/[^a-z0-9]/g,'');if(lw.length>3){freq[lw]=(freq[lw]||0)+1;}});const sorted=Object.entries(freq).sort((a,b)=>b[1]-a[1]).slice(0,20);return'Top Keywords (local):\n\n'+sorted.map(([w,c])=>w+': '+c+' times').join('\n');}
if(pl.includes('bullet')||pl.includes('list')){return'Bullet Points (local):\n\n'+sentences.map(s=>'- '+s.charAt(0).toUpperCase()+s.slice(1)+'.').join('\n');}
if(pl.includes('question')||pl.includes('faq')){const qs=sentences.filter(s=>/\?|who|what|when|where|why|how|which|can|could|should|would|is|are|do|does/i.test(s));return'Questions Found (local):\n\n'+(qs.length?qs.map(q=>'Q: '+q+(q.endsWith('?')?'':'?')).join('\n\n'):'No explicit questions found in the text.');}
if(pl.includes('headline')||pl.includes('title')){const caps=sentences.slice(0,5).map(s=>{const w=s.split(/\s+/).slice(0,8).join(' ');return w.split(' ').map(x=>x.charAt(0).toUpperCase()+x.slice(1).toLowerCase()).join(' ');});return'Headline Suggestions (local):\n\n'+caps.map((h,i)=>(i+1)+'. '+h).join('\n');}
return'Processed text (local - API unavailable):\n\nInput: '+words.length+' words, '+sentences.length+' sentences.\n\nKey sentences:\n'+sentences.slice(0,5).map(s=>'- '+s+'.').join('\n')+'\n\nNote: For advanced processing (AI summarization, translation, etc.), configure OPENAI_API_KEY in Vercel environment variables.';
}
function plWordCloud(){
const text=(document.getElementById('pl-text')?.value||'').trim();
if(!text){toast('Paste or enter text first');return;}
const stopWords=new Set(['the','a','an','is','are','was','were','be','been','have','has','had','do','does','did','will','would','shall','should','may','might','must','can','could','and','but','or','nor','for','yet','so','in','on','at','to','of','by','with','from','as','into','through','during','before','after','above','below','up','down','out','off','over','under','again','then','once','here','there','when','where','why','how','all','each','every','both','few','more','most','other','some','such','no','not','only','own','same','than','too','very','just','also','about','its','it','this','that','these','those','i','me','my','we','us','our','you','your','he','him','his','she','her','they','them','their','what','which','who','been','being','because']);
const words=text.toLowerCase().replace(/[^a-z\s]/g,'').split(/\s+/).filter(w=>w.length>2&&!stopWords.has(w));
const freq={};words.forEach(w=>{freq[w]=(freq[w]||0)+1;});
const sorted=Object.entries(freq).sort((a,b)=>b[1]-a[1]).slice(0,40);
if(!sorted.length){toast('Not enough words');return;}
const maxF=sorted[0][1];const svgW=500;const svgH=300;
const colors=['#4ade80','#22d3ee','#a855f7','#f472b6','#fbbf24','#f87171','#34d399','#60a5fa','#c084fc','#fb923c'];
let cloudSvg='';
const placed=[];
sorted.forEach(([w,c],i)=>{
const size=Math.max(10,Math.round((c/maxF)*36));
const color=colors[i%colors.length];
for(let attempt=0;attempt<50;attempt++){
const x=20+Math.random()*(svgW-40);const y=20+Math.random()*(svgH-40);
const overlap=placed.some(p=>Math.abs(p.x-x)<(p.w+w.length*size*0.5)/2&&Math.abs(p.y-y)${w}`;
placed.push({x,y,w:w.length*size*0.6});break;
}
}
});
cloudSvg+=' ';
const resultDiv=document.getElementById('pl-result');resultDiv.style.display='block';
document.getElementById('pl-synthesis-text').innerHTML=cloudSvg+'Top words: '+sorted.slice(0,10).map(([w,c])=>w+'('+c+')').join(', ')+'
';
toast('Word cloud generated');
}
function plSaveTemplate(){
const prompt=document.getElementById('pl-prompt').value.trim();
if(!prompt){toast('Write a prompt first');return;}
const name=window.prompt('Template name:',prompt.substring(0,30));
if(!name)return;
if(!S.pipelineTemplates)S.pipelineTemplates=[];
S.pipelineTemplates.push({name:name.trim(),prompt,created:new Date().toISOString()});
save();plRenderCustomTemplates();toast('Template saved: '+name.trim());
}
function plRenderCustomTemplates(){
const el=document.getElementById('pl-custom-templates');if(!el)return;
const tpls=S.pipelineTemplates||[];
if(!tpls.length){el.innerHTML='';return;}
el.innerHTML=tpls.map((t,i)=>`${esc(t.name)} x `).join('');
}
function plDeleteTemplate(idx){
if(!S.pipelineTemplates||!S.pipelineTemplates[idx])return;
S.pipelineTemplates.splice(idx,1);save();plRenderCustomTemplates();toast('Template deleted');
}
function plCopyResult() {
const text=document.getElementById('pl-synthesis-text').textContent;
navigator.clipboard.writeText(text).then(()=>toast('Copied!')).catch(()=>toast('Copy failed'));
}
function plSaveCapture() {
fetch(ASTRA_API+'/api/capture',{method:'POST',headers:{'Content-Type':'application/json','Authorization':'Bearer '+ASTRA_ADMIN_PW},body:JSON.stringify({
content:plSynthesisText,category:'pipeline',source:'pipeline-ui',sourceTitle:'Pipeline Result',type:'synthesis',tags:['pipeline','processed']
})}).then(r=>r.json()).then(d=>{
if(d.ok) toast('Saved to ASTRA!');
else toast('Save error');
}).catch(()=>toast('Save failed'));
}
function plSaveToContent(){
const text=plSynthesisText||document.getElementById('pl-synthesis-text').textContent;
if(!text){toast('No result to save');return;}
const prompt=document.getElementById('pl-prompt').value.trim();
const src=document.getElementById('pl-source').value.replace('pipeline-','');
S.content.unshift({id:Date.now(),body:text,theme:'pipeline',tags:['pipeline',src].filter(Boolean),created:new Date().toISOString()});
save();toast('Saved to Content section');
if(currentSection==='content')renderContent();
}
async function plLoadHistory() {
const histDiv=document.getElementById('pl-history');
const listDiv=document.getElementById('pl-history-list');
histDiv.style.display=histDiv.style.display==='none'?'block':'none';
if(histDiv.style.display==='none') return;
listDiv.innerHTML='Loading...
';
let results=[];
let source='none';
try {
if(ASTRA_ADMIN_PW){
const res=await fetch(ASTRA_API+'/api/pipeline',{headers:{'Authorization':'Bearer '+ASTRA_ADMIN_PW}});
const data=await res.json();
if(data.ok && data.results && data.results.length>0){results=data.results;source='cloud';}
}
} catch(e){}
if(!results.length && S.pipelineHistory && S.pipelineHistory.length){results=S.pipelineHistory;source='local';}
const hq=(document.getElementById('pl-history-search')?.value||'').toLowerCase();
if(hq)results=results.filter(r=>((r.preview||'')+(r.prompt||'')+(r.source||'')).toLowerCase().includes(hq));
if(results.length>0){
const srcColors={'pipeline-manual':'var(--accent)','pipeline-whatsapp':'#25d366','pipeline-voice':'#a855f7','pipeline-capture':'#fbbf24'};
listDiv.innerHTML=(source==='local'?'Showing local history ('+results.length+' entries)
':'')+results.map((r,i)=>{const full=r.preview||'';const short=full.length>150?full.substring(0,150)+'...':full;const sc=srcColors[r.source]||'var(--text-muted)';const srcLabel=(r.source||'').replace('pipeline-','');return ''+esc(r.inputType||'text')+' '+esc(srcLabel||'manual')+'
'+new Date(r.createdAt).toLocaleDateString('en-US',{month:'short',day:'numeric',hour:'2-digit',minute:'2-digit'})+' '+(r.prompt?'
'+esc(r.prompt)+'
':'')+'
'+esc(short)+(full.length>150?' [click to expand] ':'')+'
'+esc(full)+'
Copy To Content Delete
';}).join('');
} else {
listDiv.innerHTML='P
No pipeline history yet
Paste text, write a prompt, and hit Process
';
}
}
function plDeleteEntry(idx){
if(!confirm('Delete this pipeline entry?'))return;
if(S.pipelineHistory&&S.pipelineHistory[idx]){S.pipelineHistory.splice(idx,1);save();plLoadHistory();plLoadHistory();toast('Deleted');}
}
function plUpdateResultStats(text){
const el=document.getElementById('pl-result-stats');if(!el||!text)return;
const words=text.trim().split(/\s+/).filter(x=>x.length).length;
const chars=text.length;
const lines=text.split('\n').length;
const sents=text.split(/[.!?]+/).filter(s=>s.trim().length).length;
el.textContent=words+' words / '+chars+' chars / '+lines+' lines / '+sents+' sentences';
}
function plClearResult(){
document.getElementById('pl-result').style.display='none';
document.getElementById('pl-input-preview').style.display='none';
plAudioBlob=null;plTranscriptText='';plSynthesisText='';
document.getElementById('pl-prompt').value='';
}
async function plViewEntry(id) {
try {
const res=await fetch(ASTRA_API+'/api/pipeline',{headers:{'Authorization':'Bearer '+ASTRA_ADMIN_PW}});
const data=await res.json();
const entry=(data.results||[]).find(r=>r.id===id);
if(entry) {
document.getElementById('pl-synthesis-text').textContent=entry.preview||'(load full entry)';
document.getElementById('pl-result').style.display='block';
toast('Loaded: '+id);
}
} catch(e) { toast('Error loading entry'); }
}
// === REPOS ===
function timeAgo(dateStr){
if(!dateStr)return '';
const d=new Date(dateStr),now=new Date(),ms=now-d,s=Math.floor(ms/1000),m=Math.floor(s/60),h=Math.floor(m/60),dy=Math.floor(h/24);
if(dy>30)return d.toLocaleDateString('en-US',{month:'short',day:'numeric'});
if(dy>0)return dy+'d ago';if(h>0)return h+'h ago';if(m>0)return m+'m ago';return 'just now';
}
function reposRefresh() {
if(!S.repos || !S.repos.length) {
S.repos = [
{ name:'astra-command-center', github:'https://github.com/gabosaturno11/astra-command-center', live:'https://astra-command-center-sigma.vercel.app', role:'backend-hub', status:'active', desc:'ASTRA V2 command center, project hub, KB, whiteboard, API backend', updatedAt:new Date().toISOString() },
{ name:'saturno-bonus', github:'https://github.com/gabosaturno11/saturno-bonus', live:'https://saturno-bonus-omega.vercel.app', role:'customer-facing', status:'active', desc:'Bonus vault for SM Academy customers. 60 tools, 15 PDFs, music player.', updatedAt:new Date().toISOString() },
{ name:'titan-forge', github:'https://github.com/gabosaturno11/titan-forge', live:'https://titan-forge-ten.vercel.app', role:'internal-tools', status:'active', desc:'Internal tools collection. Bonus page moved out to saturno-bonus.', updatedAt:new Date().toISOString() },
{ name:'de-aqui-a-saturno', github:'https://github.com/gabosaturno11/de-aqui-a-saturno', live:'https://de-aqui-a-saturno-jet.vercel.app', role:'experience', status:'complete', desc:'Valentine crystal cosmic scroll. Gate, 18 chapters, 11 love dimensions.', updatedAt:'2026-02-14T00:00:00Z' },
{ name:'nexus-capture', github:'https://github.com/gabosaturno11/nexus-capture', live:null, role:'extension', status:'active', desc:'Chrome extension for universal highlight capture. Routes to ASTRA API.', updatedAt:new Date().toISOString() },
];
save();
}
const grid=document.getElementById('repos-grid');
if(!grid) return;
const rq=(document.getElementById('repo-search')?.value||'').toLowerCase();
let repos=[...(S.repos||[])];
if(rq)repos=repos.filter(r=>(r.name+' '+r.role+' '+r.desc+' '+r.status).toLowerCase().includes(rq));
const rsort=(document.getElementById('repo-sort')?.value)||'name';
if(rsort==='name')repos.sort((a,b)=>a.name.localeCompare(b.name));
else if(rsort==='status')repos.sort((a,b)=>(a.status||'').localeCompare(b.status||''));
else if(rsort==='updated')repos.sort((a,b)=>new Date(b.updatedAt||0)-new Date(a.updatedAt||0));
else if(rsort==='role')repos.sort((a,b)=>(a.role||'').localeCompare(b.role||''));
const cntEl=document.getElementById('repos-count');if(cntEl)cntEl.textContent=(S.repos||[]).length;
const roleColors={'backend-hub':'var(--accent)','customer-facing':'#22d3ee','internal-tools':'#a855f7','experience':'#f472b6','extension':'#fbbf24'};
const roleIcons={'backend-hub':' ','customer-facing':' ','internal-tools':' ','experience':' ','extension':' '};
if(!repos.length){grid.innerHTML=`R
${rq?'No matching repos':'No repos connected'}
${rq?'Try a different filter':'Click + Add to connect a repository'}
`;return;}
const renderRepoCard=r=>{
const rc=roleColors[r.role]||'var(--text-muted)';
const sc=r.status==='active'?'var(--green)':r.status==='complete'?'var(--accent-cyan)':'var(--text-muted)';
const icon=roleIcons[r.role]||'';
return `
${icon}
${esc(r.name)}
${r.live?'LIVE ':'LOCAL '}
${esc(r.role)}
${r.updatedAt?''+timeAgo(r.updatedAt)+' ':''}
${r.lastDeploy?'deployed '+r.lastDeploy+' ':''}
${esc(r.desc)}
${r.stack?`
${r.stack.split(',').map(t=>`${esc(t.trim())} `).join('')}
`:''}${r.lastCommit?`
last: ${esc(r.lastCommit)}
`:''}${r.notes?`
${esc(r.notes)}
`:''}
`;};
let repoHtml='';if(rsort==='role'||rsort==='status'){let lastGrp=null;repos.forEach(r=>{const grp=rsort==='role'?(r.role||'other'):(r.status||'unknown');if(grp!==lastGrp){const cnt=repos.filter(x=>(rsort==='role'?(x.role||'other'):(x.status||'unknown'))===grp).length;const gc=rsort==='role'?(roleColors[grp]||'var(--text-muted)'):(grp==='active'?'var(--green)':grp==='complete'?'var(--accent-cyan)':'var(--text-muted)');repoHtml+=`${esc(grp)} ${cnt}
`;lastGrp=grp;}repoHtml+=renderRepoCard(r);});}else{repoHtml=repos.map(renderRepoCard).join('');}
grid.innerHTML=repoHtml;
}
async function repoHealthCheck(){
const repos=(S.repos||[]).filter(r=>r.live);
if(!repos.length){toast('No repos with live URLs');return;}
toast('Checking '+repos.length+' live URLs...');
let ok=0,fail=0;
for(const r of repos){
try{
const res=await fetch(r.live,{mode:'no-cors',signal:AbortSignal.timeout(5000)});
r.lastCheck=new Date().toISOString();r.lastCheckOk=true;ok++;
}catch(e){r.lastCheck=new Date().toISOString();r.lastCheckOk=false;fail++;}
}
save();reposRefresh();toast(ok+' up, '+fail+' down');
}
// === REPO MODAL ===
let editingRepoName=null;
function openRepoModal(name){
editingRepoName=name||null;
document.getElementById('repo-modal-title').textContent=name?'Edit Repo':'Add Repo';
if(name){
const r=(S.repos||[]).find(x=>x.name===name);
if(r){document.getElementById('rm-name').value=r.name;document.getElementById('rm-github').value=r.github||'';document.getElementById('rm-live').value=r.live||'';document.getElementById('rm-role').value=r.role||'other';document.getElementById('rm-status').value=r.status||'active';document.getElementById('rm-desc').value=r.desc||'';document.getElementById('rm-notes').value=r.notes||'';document.getElementById('rm-lastcommit').value=r.lastCommit||'';document.getElementById('rm-stack').value=r.stack||'';document.getElementById('rm-deploy').value=r.lastDeploy||'';}
} else {
document.getElementById('rm-name').value='';document.getElementById('rm-github').value='';document.getElementById('rm-live').value='';document.getElementById('rm-role').value='other';document.getElementById('rm-status').value='active';document.getElementById('rm-desc').value='';document.getElementById('rm-notes').value='';document.getElementById('rm-lastcommit').value='';document.getElementById('rm-stack').value='';document.getElementById('rm-deploy').value='';
}
document.getElementById('repo-modal').classList.add('open');
setTimeout(()=>document.getElementById('rm-name').focus(),100);
}
function closeRepoModal(){document.getElementById('repo-modal').classList.remove('open');editingRepoName=null;}
function saveRepo(){
const name=document.getElementById('rm-name').value.trim();
if(!name){toast('Name required');return;}
const notes=document.getElementById('rm-notes').value.trim();
const lastCommit=document.getElementById('rm-lastcommit').value.trim();
const stack=document.getElementById('rm-stack').value.trim();
const lastDeploy=document.getElementById('rm-deploy').value;
const data={name,github:document.getElementById('rm-github').value.trim(),live:document.getElementById('rm-live').value.trim()||null,role:document.getElementById('rm-role').value,status:document.getElementById('rm-status').value,desc:document.getElementById('rm-desc').value.trim(),notes:notes||undefined,lastCommit:lastCommit||undefined,stack:stack||undefined,lastDeploy:lastDeploy||undefined,updatedAt:new Date().toISOString()};
if(!S.repos)S.repos=[];
if(editingRepoName){
const idx=S.repos.findIndex(r=>r.name===editingRepoName);
if(idx>=0)S.repos[idx]=data;
else S.repos.push(data);
} else {
if(S.repos.find(r=>r.name===name)){toast('Repo already exists');return;}
S.repos.push(data);
}
save();closeRepoModal();reposRefresh();toast(editingRepoName?'Updated':'Added');
}
function deleteRepo(name){
if(!confirm('Delete repo "'+name+'"?'))return;
S.repos=(S.repos||[]).filter(r=>r.name!==name);
save();reposRefresh();toast('Deleted');
}
async function reposHealthCheck(){
const repos=(S.repos||[]).filter(r=>r.live);
if(!repos.length){toast('No live URLs to check');return;}
toast('Checking '+repos.length+' live URLs...');
const results=await Promise.allSettled(repos.map(r=>fetch(r.live,{mode:'no-cors',cache:'no-cache'}).then(()=>({name:r.name,ok:true})).catch(()=>({name:r.name,ok:false}))));
const summary=results.map(r=>r.value||r.reason);
const up=summary.filter(s=>s&&s.ok).length;
toast(up+'/'+repos.length+' repos responding');
summary.forEach(s=>{if(s){const repo=(S.repos||[]).find(r=>r.name===s.name);if(repo){repo.lastCheck=new Date().toISOString();repo.lastCheckOk=s.ok;}}});
save();reposRefresh();
}
// === FOCUS TIMER ===
let focusTimerInterval=null;let focusTimerEnd=0;let focusTimerTaskId=null;let focusTimerStartedAt=null;let focusTimerMinutes=0;
function startFocusTimer(taskId,minutes){
minutes=minutes||25;
if(focusTimerInterval){clearInterval(focusTimerInterval);const fp=document.getElementById('focus-timer-float');if(fp)fp.remove();}
focusTimerTaskId=taskId||null;focusTimerEnd=Date.now()+minutes*60*1000;focusTimerStartedAt=new Date().toISOString();focusTimerMinutes=minutes;
const t=taskId?S.tasks.find(x=>x.id===taskId):null;
const panel=document.createElement('div');panel.id='focus-timer-float';
panel.style.cssText='position:fixed;bottom:20px;right:20px;background:var(--bg-surface);border:1px solid var(--accent);border-radius:12px;padding:12px 16px;z-index:9999;min-width:200px;box-shadow:0 8px 32px rgba(0,0,0,0.4)';
panel.innerHTML='Focus Mode
'+(t?''+esc(t.title)+'
':'')+''+minutes+':00
Stop +5m
';
document.body.appendChild(panel);
focusTimerInterval=setInterval(()=>{
const rem=Math.max(0,focusTimerEnd-Date.now());
const m=Math.floor(rem/60000);const s=Math.floor((rem%60000)/1000);
const disp=document.getElementById('focus-timer-display');
if(disp)disp.textContent=m+':'+String(s).padStart(2,'0');
if(rem<=0){stopFocusTimer();toast('Focus session complete!');if(focusTimerTaskId){const tk=S.tasks.find(x=>x.id===focusTimerTaskId);if(tk){tk.timeSpent=(tk.timeSpent||0)+minutes;save();renderTasks();}}}
},1000);
toast('Focus timer: '+minutes+'min'+(t?' on '+t.title.substring(0,30):''));
}
function stopFocusTimer(){
if(focusTimerInterval){clearInterval(focusTimerInterval);focusTimerInterval=null;}
const fp=document.getElementById('focus-timer-float');if(fp)fp.remove();
const elapsed=focusTimerStartedAt?Math.max(1,Math.round((Date.now()-new Date(focusTimerStartedAt).getTime())/60000)):0;
if(focusTimerTaskId){const t=S.tasks.find(x=>x.id===focusTimerTaskId);if(t){t.timeSpent=(t.timeSpent||0)+elapsed;save();renderTasks();}}
if(elapsed>0&&focusTimerStartedAt){if(!S.focusSessions)S.focusSessions=[];const t=focusTimerTaskId?S.tasks.find(x=>x.id===focusTimerTaskId):null;S.focusSessions.unshift({date:new Date().toISOString().split('T')[0],minutes:elapsed,task:t?t.title:'',startedAt:new Date(focusTimerStartedAt).toLocaleTimeString('en-US',{hour:'numeric',minute:'2-digit'}),planned:focusTimerMinutes});if(S.focusSessions.length>200)S.focusSessions.length=200;save();}
const fTaskName=focusTimerTaskId?(S.tasks.find(x=>x.id===focusTimerTaskId)||{}).title:'';
notifyFocusComplete(fTaskName);
focusTimerTaskId=null;focusTimerStartedAt=null;focusTimerMinutes=0;
}
function extendFocusTimer(mins){focusTimerEnd+=mins*60*1000;toast('+'+mins+' minutes added');}
// === FLOATING QUICK NOTE ===
function toggleQuickNote(){
let panel=document.getElementById('quick-note-panel');
if(panel){panel.style.display=panel.style.display==='none'?'flex':'none';if(panel.style.display==='flex')panel.querySelector('textarea').focus();return;}
panel=document.createElement('div');panel.id='quick-note-panel';
panel.style.cssText='position:fixed;bottom:72px;left:20px;z-index:950;width:280px;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius);padding:12px;display:flex;flex-direction:column;gap:8px;box-shadow:0 8px 32px rgba(0,0,0,0.6)';
panel.innerHTML=`Quick Note ×
Save as Content Save as Task
`;
document.body.appendChild(panel);panel.querySelector('textarea').focus();
}
function saveQuickNote(type){
const text=document.getElementById('qn-text')?.value?.trim();if(!text){toast('Type something first');return;}
if(type==='content'){S.content.unshift({id:Date.now(),body:text,type:'note',theme:'quick-note',tags:['quick-note'],created:new Date().toISOString()});save();if(currentSection==='content')renderContent();toast('Saved as content');}
else if(type==='task'){S.tasks.unshift({id:Date.now(),title:text,description:'',subtasks:[],status:'todo',priority:'p2',project:taskProjectFilter||'',due:'',created:new Date().toISOString()});save();if(currentSection==='tasks')renderTasks();toast('Saved as task');}
document.getElementById('qn-text').value='';
}
// === CONTENT WORD CLOUD ===
function contentWordCloud(){
const allText=S.content.map(c=>c.body||'').join(' ');
if(allText.trim().length<50){toast('Not enough content for word cloud');return;}
const stop=new Set(['the','be','to','of','and','a','in','that','have','i','it','for','not','on','with','he','as','you','do','at','this','but','his','by','from','they','we','her','she','or','an','will','my','one','all','would','there','their','what','so','up','out','if','about','who','get','which','go','me','when','make','can','like','time','no','just','him','know','take','people','into','year','your','good','some','could','them','see','other','than','then','now','look','only','come','its','over','think','also','back','after','use','two','how','our','work','first','well','way','even','new','want','because','any','these','give','day','most','us','is','are','was','were','been','being','has','had','does','did','may','might','shall','should','must','need','am','very','much','more','own','each','every','while','still','through','where','too','around','find','here','thing','many','well','also','between','before','after','during','without','again','same','another','such','already','since','something','anything','everything','nothing','always','never','often','really']);
const words=allText.toLowerCase().replace(/[^a-z\s]/g,'').split(/\s+/).filter(w=>w.length>2&&!stop.has(w));
const freq={};words.forEach(w=>{freq[w]=(freq[w]||0)+1;});
const sorted=Object.entries(freq).sort((a,b)=>b[1]-a[1]).slice(0,40);
if(!sorted.length){toast('No words found');return;}
const maxF=sorted[0][1];const minF=sorted[sorted.length-1][1];
const panel=document.createElement('div');panel.id='content-wordcloud-panel';
panel.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:var(--bg-surface);border:1px solid var(--border);border-radius:12px;padding:24px;z-index:9999;max-width:520px;max-height:70vh;overflow:auto;box-shadow:0 20px 60px rgba(0,0,0,0.6)';
const colors=['#4ade80','#22d3ee','#a855f7','#f472b6','#fbbf24','#60a5fa','#34d399','#fb923c'];
let cloud='';
sorted.forEach(([w,c],i)=>{
const size=Math.round(10+((c-minF)/(maxF-minF||1))*22);
const color=colors[i%colors.length];
cloud+=`${esc(w)} `;
});
cloud+='
';
panel.innerHTML='Content Word Cloud X
'+sorted.length+' unique words from '+S.content.length+' items
'+cloud;
document.body.appendChild(panel);
}
if('serviceWorker' in navigator){navigator.serviceWorker.register('/sw.js').catch(()=>{});}